我想定义:
square :: Integer -> Integer
square = round . (** 2)
我得到了:
<interactive>:9:9: error:
• No instance for (RealFrac Integer) arising from a use of ‘round’
• In the first argument of ‘(.)’, namely ‘round’
In the expression: round . (** 2)
In an equation for ‘square’: square = round . (** 2)
<interactive>:9:18: error:
• No instance for (Floating Integer)
arising from an operator section
• In the second argument of ‘(.)’, namely ‘(** 2)’
In the expression: round . (** 2)
In an equation for ‘square’: square = round . (** 2)
我仍然是这种语言的新手,我似乎无法将Floating的实例转换为Integer。有谁知道我该怎么办?
答案 0 :(得分:5)
Haskell有多个不同类型的指数函数:
(^) :: (Num a, Integral b) => a -> b -> a
(^^) :: (Fractional a, Integral b) => a -> b -> a
(**) :: Floating a => a -> a -> a
您正在寻找的只是(^)
。有了它,您甚至不需要round
:
square :: Integer -> Integer
square = (^ 2)
答案 1 :(得分:5)
这是Alec答案的附录,这是正确的,可以帮助您理解错误信息。 (**)
的类型是
(**) :: (Floating a) => a -> a -> a
所以
(** 2) :: (Floating a) => a -> a
(因为文字2
可以是我们需要的任何数字类型)。但a
为Integer
,因为您的函数声明为Integer
作为输入。所以现在
(** 2) :: Integer -> Integer --provided that there is a `Floating Integer` instance
这解释了您的第二个错误,因为没有Floating
Integer
实例 - Integer
不支持sin
等浮点运算(以及任意取幂)实数)。
然后将此函数的输出(Integer
)传递给round
,其类型为
round :: (RealFrac a, Integral b) => a -> b
我们知道输入a
是Integer
,因为它来自我们讨论的(** 2)
,而输出b
也是Integer
,因为函数的输出声明为Integer
。所以现在你有了
round :: Integer -> Integer
--provided there are `Integral Integer` and `RealFrac Integer` instaces
有Integral
Integer
个实例,因此使用了该实例,但没有RealFrac
Integer
个实例,这解释了您的第一个错误。 Integer
不支持类似于理性的操作,例如提取分子(尽管我认为它们可以......)。
答案 2 :(得分:1)
作为@ luqui回答的附录,如果您想修复错误(而不是仅仅关注@ Alec的优秀解决方案),您可以将Integer
参数转换为{ {1}}实例优先:
Floating