模式匹配中的冲突定义
我刚刚开始学习 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)现在抱怨 “碰撞”的定义冲突
我不明白,这些定义会如何冲突,是吗?
谢谢!
I just started learning Haskell and I ran into a problem in 2-adic type classes. Here's the important code:
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
...
The compiler (GHC 6.12.1) now complains aboutConflicting definitions for 'collides'
I don't see, how the definitions would conflict, do you?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最有可能的罪魁祸首是“...”中某处的布局错误,导致两条
碰撞
线被分成两个单独的块。“碰撞”的定义冲突
意味着同一范围内有两个不同的地方定义了碰撞
。不知何故,要么这两行被中断,因此编译器将它们视为单独的,要么“...”部分中存在错误,以某种方式在一个范围内定义了两次碰撞。有两种主要方法可以解决
定义冲突
错误。首先,同一函数定义中的两个绑定可以尝试绑定同一变量,如foo xx = ...
中所示。这是不允许的,因为它定义了 x 两次。另一种情况(我怀疑在您的代码中适用的情况)是同一定义的两个部分被另一个定义“中断”时。编译器将其视为两个单独的定义。例如:
这也是不允许的,因为它(再次)定义了相同的名称(
foo
)两次。中断可能并不明显,特别是在您不小心混合制表符和空格的情况下(并且您的编辑器使用的不是 Haskell 假设的每个空格 8 个制表符)。它可能在编辑器中显示为 where 子句中的缩进行,但由于制表符宽度的差异,编译器会发现它与
foo
对齐,从而使第二个foo
变成另一个定义与第一个定义相冲突。在布局敏感的语言中,通常认为最好只在代码中使用空格,或者至少确保编辑器为其选项卡使用正确数量的空格。对于 Haskell 来说,是 8。
The most likely culprit is a layout error somewhere in your "..." that causes the two
collides
lines to be separated into two separate blocks.Conflicting definitions for 'collides'
means that there are two different places in the same scope that are definingcollides
. Somehow either those two lines are interrupted so the compiler sees them as separate, or there's an error in the "..." part that somehow definescollides
twice in one scope.There are 2 main ways to trip the
Conflicting definitions
error. First, two bindings in the same function definition can try to bind the same variable, as infoo x x = ...
. That's not allowed, because it definesx
twice.The other (which is the one that I suspect applies in your code) is when two parts of the same definition are "interrupted" by another definition. The compiler sees that as two separate definitions. For example:
This is not allowed either, because it (again) defines the same name (
foo
) twice.The interruption may not be obvious, especially in cases where you accidentally mix tabs and spaces (and your editor uses something other than the 8 tabs per space that Haskell assumes). It can appear in your editor to be an indented line in a where clause but due to differences in tab width the compiler sees it aligned with
foo
, making the secondfoo
into another definition conflicting with the first.It is generally considered a good idea in layout-sensitive languages to only use spaces in your code, or at the very least to make sure that your editor is using the right number of spaces for its tabs. For Haskell, that is 8.