模式匹配中的冲突定义

时间:2010-10-23 12:53:09

标签: haskell types pattern-matching

我刚刚开始学习Haskell,我遇到了2-adic类型的问题。这是重要的代码:

data Rectangle = NoRect | Rect (Float,Float) (Float,Float) | Pane
      deriving (Show)
class Collision s1 s2 where
      collides ::  s1 -> s2 -> Bool

instance (Collision Rectangle Rectangle) where
    collides (Rect (aOrX, aOrY) (aCorX, aCorY)) 
             (Rect (bOrX,bOrY) (bCorX,bCorY)) = ...
    collides Pane _ = True
    ...

编译器(GHC 6.12.1)现在抱怨 Conflicting definitions for 'collides'

我没有看到,定义会如何冲突,对吗?

谢谢!

1 个答案:

答案 0 :(得分:3)

最可能的罪魁祸首是“...”中某处的布局错误导致两条collides行分成两个独立的块。 Conflicting definitions for 'collides'表示同一作用域中有两个定义collides的不同位置。不知何故,这两行是否被中断,因此编译器将它们视为独立的,或者“...”部分中的错误在某个范围内以某种方式定义collides两次。

有两种主要方法可以解决Conflicting definitions错误。首先,同一函数定义中的两个绑定可以尝试绑定同一个变量,如foo x x = ...中所示。这是不允许的,因为它定义了x两次。

另一个(我怀疑在你的代码中应用的那个)是当同一定义的两个部分被另一个定义“中断”时。编译器将其视为两个单独的定义。例如:

foo True = ...
bar = ...
foo False = ...

这也是不允许的,因为它(再次)定义了两次相同的名称(foo)。

中断可能并不明显,尤其是在您不小心混合制表符和空格的情况下(并且您的编辑器使用Haskell假定的每个空间的8个制表符以外的其他内容)。它可以在编辑器中显示为where子句中的缩进行,但由于选项卡宽度的不同,编译器将其与foo对齐,使第二个foo成为另一个与第一个定义冲突的定义。

在布局敏感语言中,通常认为只在代码中使用空格,或者至少要确保编辑器为其选项卡使用正确数量的空格。对于Haskell,那就是8。