2009-12-28 55 views
8

我正在学习Haskell。我已经创建了函数,它返回乘法表到'b'的基数'n'。数字填充为'w'数字。作为最后一步,我想自动计算'w'。为什么不能编译?没有实例(浮动INT)

-- 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)) 

回答

10

logBase需要其实现浮动类型类两个参数。在将参数传递给logBase之前,您需要从参数中调用参数。这编译为我6.10.3:

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

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

5

logBase被声明为在浮点类型上工作。 Int不是浮点类型,有no automatic conversion in 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))) 
+0

我想你还需要'(fromIntegral base)'。 –

+0

@Jason:不是Dan提供这种功能的类型,你不会。 – Chuck

+0

是的,取决于你想如何使用它。要么就像我拥有它,如果可以更改类型签名,或者如果不是,则使用Andy的版本。 –

3

从前奏:

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

这意味着使用logBase您必须使用浮动型。但int是不是一个浮点类型,并没有对数字类型的自动转换,因此你必须把它从int转换为浮动类型:

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

的toEnum功能需要一个int参数,并返回“枚举“类型。好的一面是,浮子枚举的一个实例,所以你可以使用它

toEnum :: Enum a => Int -> a 

你应该读/记录您关于在Haskell数值类型(数字,分数,标准型类整型,浮点... ),因为他们经常在代码中弹出,学习转换可能会有用。

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