了解Haskell类型类在类型声明中的使用

时间:2018-12-28 00:06:58

标签: haskell

当我们有一个使用==比较运算符比较两件事的函数时,我们在类型声明中添加类似Eq a => a...的内容;但这并非总是如此。

例如,给定以下功能:

tail' xs = if length xs == 0
          then []
          else drop 1 xs

我们利用了==比较运算符,因此我认为正确的类型声明应为:

tail':: (Eq a) => [a] -> [a]

但是,运行:t tail'告诉我正确的类型十进制是:

tail':: [a] -> [a]

为什么会这样?为什么在类型声明中不需要Eq

1 个答案:

答案 0 :(得分:6)

Eq a => ta必须是类型Eq的{​​{1}}的实例。作为t实例的类型意味着为该类型定义了Eq。但是在==的定义中,您永远不会在tail'上使用==,即使是通过代理也是如此。 a的实际用法是在==中。 length xs == 0(和length xs)的类型为0,并且Int已经是Int的实例,因此我们已经知道它具有{{1} }定义。由于您从未在Eq上使用==,因此不需要==约束。

但是,如果您说的a似乎是等效的(都测试列表是否为空),则您将受到Eq a约束。这是因为xs == []上的Eq a需要一个==约束,因为它在每个列表的条目上使用[a]来比较列表。但是,由于您可以使用Eq a(或者更好的是==),所以这种增加的约束是虚假的,应该避免。

(顺便说一句,length xs == 0甚至不需要null xs,但这与所问的问题无关。)