9

我正在学习 Haskell。我创建了函数,它在基数“b”中返回乘法表直到“n”。数字被填充到“w”位。作为最后一步,我想自动计算“w”。为什么这不编译?

-- Number of digits needed for the multiplication table n*n in base 'base'
nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor ( logBase base (n*n)) 

错误:

No instance for (Floating Int)
     arising from a use of `logBase' at C:\haskel\dgnum.hs:4:24-38
   Possible fix: add an instance declaration for (Floating Int)
   In the first argument of `floor', namely `(logBase b (n * n))'
   In the second argument of `(+)', namely `floor (logBase b (n * n))'
   In the expression: 1 + floor (logBase b (n * n))
4

3 回答 3

13

logBase 采用两个参数来实现浮动类型类。在将参数传递给 logBase 之前,您需要在参数上调用 fromIntegral。这是用 6.10.3 为我编译的:

nOfDg :: Int -> Int-> Int
nOfDg n base = 1 + floor ( logBase (fromIntegral base) (fromIntegral (n*n)))

你必须记住 Haskell 是非常强类型的,所以你不能假设提供给你的函数的 Int 参数会自动强制转换为日志函数通常采用的浮点数。

于 2009-12-28T17:22:41.350 回答
5

logBase被声明为在浮点类型上工作。Int 不是浮点类型,在 Haskell 中没有自动转换。试试这个:

-- Number of digits needed for the multiplication table n*n in base 'base'
nOfDg :: Int -> Float -> Int
nOfDg n base = 1 + floor (logBase base (fromIntegral (n*n)))
于 2009-12-28T17:27:45.747 回答
3

从前奏曲:

logBase :: Floating a => a -> a -> a

这意味着使用 logBase 您必须使用浮动类型。但是 Int 不是浮点类型,数字类型没有自动转换,所以你必须将它从 Int 转换为 Floating 类型:

nOfDg n base = 1 + floor ( logBase (toEnum base) (toEnum n))

toEnum 函数接受一个 int 作为参数并返回一个“Enum”类型。好的部分是 Float 是 Enum 的一个实例,所以你可以使用它

toEnum :: Enum a => Int -> a

您应该阅读/记录有关数字类型(Num、Fractional、Integral、Floating...)的标准类型类的信息,因为它们经常在代码中弹出,学习转换可能很有用。

编辑:这本Haskell Wiki Book提供了一个非常有用的标准类型类之间关系的图形,包括数字类型。

于 2009-12-28T17:28:21.580 回答