为什么Num不能与0比较?

时间:2013-09-04 21:12:42

标签: haskell typeclass

此功能不正确,无法编译:

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

由于表达式Num0a == 0之间的比较,这不起作用。将Num更改为Integral会使其成为有效的功能。

这个邪恶的巫术是什么让我把我的数字与0进行比较?!

3 个答案:

答案 0 :(得分:24)

Num要求实例实施+*abssignumfromInteger。请注意,==不在列表中!它是必须实现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(以及IntDouble)包含两个实例:instance Num Integerinstance 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