模式匹配中的冲突定义

发布于 2024-09-29 10:59:52 字数 512 浏览 1 评论 0原文

我刚刚开始学习 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 about
Conflicting definitions for 'collides'

I don't see, how the definitions would conflict, do you?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一个人练习一个人 2024-10-06 10:59:52

最有可能的罪魁祸首是“...”中某处的布局错误,导致两条碰撞线被分成两个单独的块。 “碰撞”的定义冲突意味着同一范围内有两个不同的地方定义了碰撞。不知何故,要么这两行被中断,因此编译器将它们视为单独的,要么“...”部分中存在错误,以某种方式在一个范围内定义了两次碰撞。

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

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

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

这也是不允许的,因为它(再次)定义了相同的名称(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 defining collides. Somehow either those two lines are interrupted so the compiler sees them as separate, or there's an error in the "..." part that somehow defines collides 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 in foo x x = .... That's not allowed, because it defines x 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:

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

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 second foo 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文