为什么Num不能与0比较?

Cor*_*ein 9 haskell typeclass

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

checkIsZero :: (Num a) => a -> String
checkIsZero a = if a == 0
                  then "Zero"
                  else "Not zero"
Run Code Online (Sandbox Code Playgroud)

由于a Num0表达式之间的比较,这不起作用a == 0.更改NumIntegral使其成为有效的函数.

什么是这个邪恶的巫术,不让我比较我的数字0?!

jto*_*bin 24

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

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

checkIsZero :: (Eq a, Num a) => a -> String
checkIsZero a | a == 0    = "Zero"
              | otherwise = "Not zero"
Run Code Online (Sandbox Code Playgroud)

Integral因为作为Integral必须的实例的东西本身就是一个实例Ord,而它必须是一个实例Eq.

您可以使用hoogle检查所有这些内容并深入挖掘源代码.


Chr*_*lor 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
Run Code Online (Sandbox Code Playgroud)

因为你不能Eq为函数编写实例.

  • @BenMillwood我会说那些人不够富有想象力.有关示例用例,请参阅[本文](http://conal.net/papers/beautiful-differentiation/beautiful-differentiation.pdf),其中详细介绍了在Haskell中实现自动微分的简单方法,其中包括`cos这样的行= cos> <negate sin`(cos(x)的导数是-sin(x))和`log = log> <recip`(log(x)的导数是x的倒数). (5认同)
  • 这不仅适用于此类函数实例,还适用于符号代数类型,无限精度实数,自动导数类型...... (4认同)
  • 我想有些人会认为你对给定实例的描述是"有用的"! (2认同)
  • @BenMillwood - 数学家数百年来一直使用这种符号.它在Haskell中看起来很奇怪,因为我们错误地创建了一个名为`Num`的类型类,而不是名为`LinearSpace`,`Field`,'Algebra`等的类型类. (2认同)