此函数不正确,无法编译:
checkIsZero :: (Num a) => a -> String
checkIsZero a = if a == 0
then "Zero"
else "Not zero"
由于表达式中的aNum
和之间的比较,这不起作用。更改为使其成为有效功能。0
a == 0
Num
Integral
不让我和我的数字比较的邪恶魔法是什么0
?!
Num
需要实例来实现+
, *
, abs
,signum
和fromInteger
. 请注意,==
不在列表中!Eq
它是必须实现的类型类的实例==
。
所以,Num
约束是不够的——你也需要一个Eq
约束。下面将编译。
checkIsZero :: (Eq a, Num a) => a -> String
checkIsZero a | a == 0 = "Zero"
| otherwise = "Not zero"
Integral
之所以有效,是因为作为 的实例的事物Integral
本身必须是 的实例Ord
,而后者又必须是 的实例Eq
。
您可以通过使用hoogle并挖掘源代码来检查所有这些内容。
不需要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
为函数编写实例。
如果 data 是 的实例Num a
,则它不是被授权者,即此数据是 的实例Eq a
。
Integer
(and Int
, Double
) 有两个实例:instance Num Integer
and 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