`([] ==)[]`的类型如何推断出haskell?

时间:2010-05-21 17:55:35

标签: haskell types type-inference type-systems

这听起来很傻,但我无法理解。为什么表达式[] == []可以输入?更具体地说,哪种类型(在类Eq中)被推断为列表元素的类型?

在ghci会话中,我看到以下内容:

Prelude> :t (==[])
(==[]) :: (Eq [a]) => [a] -> Bool

但约束Eq [a]也暗示Eq a,如下所示:

Prelude> (==[]) ([]::[IO ()])

<interactive>:1:1:
No instance for (Eq (IO ()))
  arising from use of `==' at <interactive>:1:1-2
Probable fix: add an instance declaration for (Eq (IO ()))
In the definition of `it': it = (== []) ([] :: [IO ()])

因此,在[] == []中,类型检查器必须假定列表元素是类Eq中的某种类型。但是哪一个? []的类型只是[a],这肯定比Eq a =&gt;更通用。 [A]。

恕我直言,这应该是模棱两可的,至少在Haskell 98中(这就是我们所说的)

2 个答案:

答案 0 :(得分:19)

GHCi有extended rules for type defaulting,这就是你绊倒的原因。在这种情况下,我相信它会将模糊类型默认为()。 GHCi表现出不同的微妙方式对于更好的交互性来说是好的,但它们偶尔会导致混淆......

答案 1 :(得分:1)

GHC推断最常见的类型:

  

(== [])::(Eq a)=&gt; [a] - &gt;布尔

应该理解为:

  • 如果你有一个Eq a的实例,
  • 然后Haskell可以从那些'a'到Bool
  • 的列表中给你一个函数

所以是的,这里的含义是你有一个Eq实例用于列表的元素,GHC已经有一个列表实例(依赖于元素的Eq),所以我们得到了一个很好的通用类型。

类型检查器“假定”您可以在特定类型调用时提供Eq实例。

我无法重现Eq [a]约束的结果。