10

此函数不正确,无法编译:

checkIsZero :: (Num a) => a -> String
checkIsZero a = if a == 0
                  then "Zero"
                  else "Not zero"

由于表达式中的aNum和之间的比较,这不起作用。更改为使其成为有效功能。0a == 0NumIntegral

不让我和我的数字比较的邪恶魔法是什么0?!

4

3 回答 3

24

Num需要实例来实现+, *, abs,signumfromInteger. 请注意,==不在列表中!Eq它是必须实现的类型类的实例==

所以,Num约束是不够的——你也需要一个Eq约束。下面将编译。

checkIsZero :: (Eq a, Num a) => a -> String
checkIsZero a | a == 0    = "Zero"
              | otherwise = "Not zero"

Integral之所以有效,是因为作为 的实例的事物Integral本身必须是 的实例Ord,而后者又必须是 的实例Eq

您可以通过使用hoogle并挖掘源代码来检查所有这些内容。

于 2013-09-04T21:23:20.480 回答
10

不需要Eq实例来定义Num实例的原因是它会排除有用的实例,例如

instance Num b => Num (a -> b) where
    f + g    = \x -> f x + g x
    f - g    = \x -> f x - g x
    f * x    = \x -> f x * g x
    abs f    = \x -> abs (f x)
    signum f = \x -> signum (f x)
    fromInteger = const . fromInteger

因为您不能Eq为函数编写实例。

于 2013-09-04T22:10:46.887 回答
0

如果 data 是 的实例Num a,则它不是被授权者,即此数据是 的实例Eq a

Integer(and Int, Double) 有两个实例:instance Num Integerand instance Eq Integer, and 程序是有效的

Integral定义为

class (Real a, Enum a)=> Integral a where ...
class (Num a, Ord a)=> Real a where ...
class Eq a => Ord a where ...

 ~= class (Num a, Eq a, Enum a)=> Integral a where ... --means
于 2013-09-04T22:11:57.970 回答