16

这听起来很愚蠢,但我无法理解。为什么可以输入表达式 [] == [] 呢?更具体地说,哪个类型(在 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。但是哪一个?[] 的类型只是 [a],这肯定比 Eq a => [a] 更通用。

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

4

2 回答 2

19

GHCi为类型默认提供了扩展规则,这让您感到困惑。在这种情况下,我相信它会将模糊类型默认为(). 为了更好的交互性,GHCi 行为不同的微妙方式很好,但它们偶尔会导致混乱......

于 2010-05-21T18:22:06.647 回答
1

GHC 推断出最一般的类型:

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

它应该读作:

  • 如果你有一个 Eq a 的实例,
  • 那么 Haskell 可以为您提供从那些 'a's 到 Bool 的列表中的函数

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

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

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

于 2010-05-21T18:10:51.867 回答