Haskell为什么“Num x”需要“Show x”?

时间:2013-10-11 21:49:47

标签: haskell

最近我使用LYAH查看了Haskell。

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

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。

的朋友

因此,如果Num中的所有内容都是ShowEq的子集,为什么我需要将类型签名更改为foo :: (Num x, Show x) => x -> String才能使其生效?难道不可能推断Num也可以显示吗?

4 个答案:

答案 0 :(得分:18)

LYAH的信息很旧。 release notes for GHC 7.4.1说:

  

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

你需要写,

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

(事实上,您编写的foo不需要Num x,因此您可以省略它以避免不必要的约束。)

答案 1 :(得分:3)

Num Show的实例也是EqShow的实例,used to be {} no longer the case

您还需要添加{{1}}约束。

答案 2 :(得分:3)

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

GHC,最流行的Haskell编译器,与标准不同,不需要任何编译指示。这样做是为了让applicative functor成为Num的实例并享受重载语法带来的好处。

答案 3 :(得分:1)

你不应该写:

(Num x) => x -> String

而不是

(Num x) x -> String

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