【问题标题】:How is the type of `([] ==) []` inferred haskell?`([] ==) []` 的类型如何推断haskell?
【发布时间】:2011-02-22 11:37:44
【问题描述】:

这听起来很愚蠢,但我无法理解。为什么可以输入表达式 [] == [] ?更具体地说,哪个类型(在 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 中(这就是我们正在谈论的)

【问题讨论】:

  • 使用 GHC(不是 GHCi)我有 Ambiguous type variable `a' in the constraint `Eq a' arising from a use of `=='
  • @Kenny - 是的,这就是我在 ghci 中尝试之前所期望的 - 我的惊喜越大。感谢您的提示,现在我的世界秩序已恢复 :)
  • 有趣的是,Hugs 给出了表达式[] == [] 类型Eq a =&gt; Bool
  • 对不起“necroposting”,但没有办法指定[] == [] 的上下文是吗?没有专门[]自己。

标签: haskell types type-inference type-systems


【解决方案1】:

GHC 推断最一般的类型:

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

应该读作:

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

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

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

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

【讨论】:

  • 虽然上面的肯尼用 GHC 得到了不同的结果。注意:我们说的是 haskell 98,我相信一些花哨的 GHC 扩展足够聪明,可以正确输入,但我仍然不明白到底如何。恕我直言,这确实是一个模棱两可的案例。
  • @Ingo: (== []) 没有歧义,只是像往常一样多态;它将在 GHCi 或其他方式中以相同(并且正确)的方式工作。至于 GHC 扩展,您可以启用与 GHCi 相同的扩展默认设置,但我不知道您为什么要...
  • @Ingo:哇,复古!你有粗毛地毯,也听迪斯科吗? :) 说真的,新版本有很好的功能,为什么不升级......
  • GHC 6.4.2 已发布 5 年前发布。我们现在处于 GHC 6.12.2。
  • @Don Stewart: i.imgur.com/Bz0DR.png 这些不是不合理的搜索词,是不是......?我什至不知道...
【解决方案2】:

GHCi 有 extended rules for type defaulting,,这让你大吃一惊。在这种情况下,我相信它会将模糊类型默认为()。为了更好的交互性,GHCi 行为不同的微妙方式很好,但它们偶尔会导致混乱......

【讨论】:

  • @camccann:运行ghci -Wall。然后[] == [] 得到Warning: Defaulting the following constraint(s) to type '()'
  • 扩展默认值仅在您想要显示或运行代码时才重要。 :: (Eq a) => [a] -> Bool 类型是完全正确的。
  • @Don Stewart:这种类型当然很好——我认为让 Ingo 感到困惑的是([] == []) :: Bool,默认为() 来满足模棱两可的Eq a 约束,正如yairchu 所展示的那样.
  • 当然,这是默认工作。但他的初始类型似乎是错误的——没有 Eq [a] 约束。
  • @Ingo:呵呵。 (其实GHC 6.4.2 is released in 2006,也就是4年前。现在的版本是6.12.2,也就是相隔4个大版本。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多