【问题标题】:Ambiguous occurrence '=='模棱两可的出现'=='
【发布时间】:2014-08-12 23:40:06
【问题描述】:

我只是在学习 Haskell,还在尝试弄清楚事情是如何工作的。

所以我正在创建一个列表类,它可以包含IntChar 的混合。

data Algebra = Empty
|   Nmbr Int Algebra
|   Smbl Char Algebra

然后我尝试使它成为Eq的实例

instance Eq Algebra where
Empty == Empty              = True
(Nmbr x xl) == (Nmbr y yl)  = (x == y) && (xl==yl)
(Smbl x xl) == (Smbl y yl)  = (x == y) && (xl==yl)
_ == _                  = False

我得到一个Ambiguous occurrence == 编译错误。它无法区分Main.==Prelude.==。如果我手动将所有== 替换为Main.==Prelude.==,那么它编译得很好。

我不明白为什么编译器在这里遇到这么多困难。 xy 在每种情况下都明确定义为 IntChar。我已经将我正在做的事情与众多教程示例(例如http://www.haskell.org/tutorial/classes.html)进行了比较,但我无法确定为什么编译器在这种情况下如此混蛋:P

【问题讨论】:

  • 另一个问题:deriving Eq 是否尝试做与我的代码完全相同的事情?我无法很好地解释 deriving 的工作原理。
  • 是的,确实如此。请参阅official language report

标签: haskell instance ambiguous


【解决方案1】:

您需要缩进 instance 定义的正文:

instance Eq Algebra where
  Empty == Empty              = True
  (Nmbr x xl) == (Nmbr y yl)  = (x == y) && (xl==yl)
  (Smbl x xl) == (Smbl y yl)  = (x == y) && (xl==yl)
  _ == _                  = False

否则编译器会将其视为两件事:

  • 具有空主体的instance Eq Algebra,生成a == b = not (a /= b) 的默认定义,反之亦然。

  • 一个名为==的新中缀运算符的定义。

然后在您的代码中使用== 现在会在来自Eq(在Prelude 中定义)的== 和您代码中的== (Main) 之间产生歧义。

是的,deriving Eq 为您提供了这种结构上的平等。

【讨论】:

  • 哇!我发誓没有人解释过缩进是 Haskell 编码的必要部分。非常感谢!
  • @StephenDouglasAllen:Haskell 中的缩进是花括号和分号的语法糖。查看 Haskell 报告了解确切定义:haskell.org/onlinereport/haskell2010/…
  • 另一个问题:data 语句需要缩进吗?我假设不是因为 | 符号将它们组合在一起,对吧?
  • @StephenDouglasAllen 是的,他们是需要的。您给出的 data 定义不适合我。另外,顺便说一句,我建议使用空格而不是制表符(以防万一您使用制表符)。使用选项卡在 Haskell 中进行有效编程肯定是可能的,但如果您不习惯这种风格,它可能会不太直观。
  • 在 Haskell 中使用制表符编程绝对可能,但是在 Haskell 代码中使用制表符就像在 C 中使用所有单字母变量名:它不是必需 赢得一场混淆编程竞赛,但它肯定有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
相关资源
最近更新 更多