Haskell 模式匹配中的冲突定义

Haskell 模式匹配中的冲突定义,haskell,types,pattern-matching,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

我刚开始学习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)现在抱怨 “碰撞”的定义冲突

我不明白,这些定义会有什么冲突,是吗


谢谢

最可能的罪魁祸首是“…”中的某个布局错误,该错误导致两个
冲突的
行被分隔为两个单独的块<代码>冲突的“碰撞”定义
意味着在同一范围内有两个不同的位置正在定义
碰撞
。不知何故,要么这两行被中断,使编译器将它们视为独立的,要么在“…”部分中有一个错误,它在一个范围内定义了两次冲突

有两种主要方法可以触发冲突定义的
错误。首先,同一函数定义中的两个绑定可以尝试绑定同一个变量,如
foox=…
。这是不允许的,因为它定义了两次
x

另一种情况(我怀疑这一点适用于您的代码)是当同一定义的两个部分被另一个定义“中断”时。编译器将其视为两个独立的定义。例如:

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

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


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

无法复制。当将
替换为false并启用MultiparamTypeClass时,您的代码对我来说编译得很好。@sepp2k,哇,我做了完全相同的事情,并在您之后1分钟发布了我的答案!对我来说,它不是但编译得很好。除了
MultiParamTypeClasses
之外设置的任何附加标志?尝试删除
中的内容,然后让类型正常工作。@sepp2k,HaskellElephant:mee too;)错误应该包含行号,您可以发布它们并完整编码吗?