25

这个功能:

hola :: (Integral a) => a -> String
hola 1 = "OK"
hola _ = "asdf"

工作正常。但是这个:

hola :: (Num a) => a -> String
hola 1 = "OK"
hola _ = "asdf"

无法编译:“无法从文字 '1' 推导出 (Eq a)”

我真的不明白。我正在阅读一个教程,上面说

“Integral 也是一个数字类型类。Num 包括所有数字,包括实数和整数,Integral 仅包括整数(整数)数。在这个类型类中是 Int 和 Integer。” http://learnyouahaskell.com/types-and-typeclasses

为什么我不能使用 Num?

4

2 回答 2

33

这是去年 9 月 / 10 月在最新版本的基本包中提出Eq并接受的一项最新更改,Show不再是Num. 自那次更改以来,没有发布新版本的语言报告,所以它还没有出现在报告中。而且由于它是最近的,它还没有进入许多教程或书籍。

针对数字文字的“模式匹配”是 的隐式应用(==),因此需要一个Eq实例才能使其工作。现在不能再从Num约束中推断出该实例,因此(相当新的 :D)编译器拒绝仅具有Num约束的代码。

ButIntegral是 的子类Real,它Ord(因此Eq)作为超类,因此有效。

于 2012-10-07T12:02:36.667 回答
9

正如 Daniel Fischer 所说,它曾经有效,但现在无效,因为Num并且Eq被拆分了,所以Num a不再暗示Eq a。要修复您的代码,只需Eq a明确说明:

hola :: (Num a, Eq a) => a -> String
hola 1 = "OK"
hola _ = "asdf"
于 2012-10-07T15:45:27.960 回答