我试图理解 haskell 错误消息,因为它们让新手程序员感到困惑。我能找到的最简单的例子是这样的:
Prelude> 1 + True
<interactive>:2:3:
No instance for (Num Bool)
arising from a use of `+'
Possible fix: add an instance declaration for (Num Bool)
In the expression: 1 + True
In an equation for `it': it = 1 + True
为什么编译器无论参数顺序如何都会查找(Num Bool)?为什么我定义以下内容后它会起作用?
instance Num Bool where (+) a b = True;
[...]
Prelude> 1 + True
True
如何确保仅当第二个参数也是(Num Bool)时(+)才能应用于(Num Bool) ?
最佳答案
您收到此错误消息是因为 1
和 +
都是多态的 - 它们都可以适用于不同的类型!
看一下:
Prelude> :t 1
1 :: Num a => a
Prelude> :t (+)
(+) :: Num a => a -> a -> a
因此,1
和 +
对于 Num
中的任何类型都有意义> 类。因此,当您编写 1 + Bool
时,1
可能实际上是 Bool
,如果 Bool
有一个 Num
实例。事实上,您可以自己这样做:
instance Num Bool where
fromInteger x = x /= 0
(+) = (&&)
...
一旦你这样做了,1 + True
就会真正起作用。您还可以使用数字文字作为 bool 值:
*Main> 1 :: Bool
True
*Main> 1 + True
True
这也解释了为什么无论参数的顺序如何,您都会得到相同的错误:代码中唯一的实际问题是 True
- 如果有效,其他所有内容也会发生。
关于使用类型类进行 Haskell 函数参数类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19694614/