13

最近我看了一下 Haskell,使用LYAH

我在搞乱类型类并编写了这个快速测试函数:

foo :: (Num x) => x -> String
foo x = show x ++ "!"

但这会产生此错误:

test.hs:2:9:
    Could not deduce (Show x) arising from a use of `show'
    from the context (Num x)
    bound by the type signature for foo :: Num x => x -> String
    at test.hs:1:8-29
    Possible fix:
      add (Show x) to the context of
        the type signature for foo :: Num x => x -> String

但根据 LYAH 的说法:

要加入 Num,类型必须已经与 Show 和 Eq 成为朋友。

因此,如果其中的所有内容都是andNum的子集,为什么我需要将类型签名更改为才能正常工作?难道不应该可以推断出 a也是可显示的吗?ShowEqfoo :: (Num x, Show x) => x -> StringNum

4

4 回答 4

19

LYAH 中的信息是旧的。GHC 7.4.1的发行说明说:

Num 类不再具有 Eq 或 Show 超类。

你需要写,

foo :: (Num x, Show x) => x -> String

(事实上​​,foo你写的不需要Num x,所以你可以省略它以避免不必要的约束。)

于 2013-10-11T21:54:25.437 回答
3

过去一个Num实例也是Showand的一个实例Eq,但现在已经不是这样了

您还需要添加一个Show约束。

于 2013-10-11T21:54:43.640 回答
3

Haskell,982010都要求 Num 的所有实例也是 Show 和 Eq 上的实例。这在很大程度上是历史的偶然。

GHC 是最流行的 Haskell 编译器,它与这里的标准不同,不需要任何 pragma。这样做是为了允许应用函子成为 Num 的实例并享受重载语法的好处。

于 2013-10-17T15:45:14.317 回答
1

你不应该写:

(Num x) => x -> String

代替

(Num x) x -> String

据我所知,这种继承至少已经过时了。

于 2013-10-11T21:53:16.857 回答