此功能不正确,无法编译:
checkIsZero :: (Num a) => a -> String
checkIsZero a = if a == 0
then "Zero"
else "Not zero"
由于表达式Num
中0
和a == 0
之间的比较,这不起作用。将Num
更改为Integral
会使其成为有效的功能。
这个邪恶的巫术是什么让我把我的数字与0
进行比较?!
答案 0 :(得分:24)
Num
要求实例实施+
,*
,abs
,signum
和fromInteger
。请注意,==
不在列表中!它是必须实现Eq
的{{1}}类型类的实例。
因此,==
约束是不够的 - 您也需要Num
约束。以下将编译。
Eq
checkIsZero :: (Eq a, Num a) => a -> String
checkIsZero a | a == 0 = "Zero"
| otherwise = "Not zero"
有效,因为Integral
的实例必须是Integral
的实例,而Ord
的实例必须是Eq
的实例。
您可以使用hoogle检查所有这些内容并深入了解来源。
答案 1 :(得分: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
实例。
答案 2 :(得分:0)
如果数据是Num a
的实例,则不是受让人,此数据是Eq a
的实例。
Integer
(以及Int
,Double
)包含两个实例:instance Num Integer
和instance Eq Integer
,程序有效
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