模式匹配中的定义冲突 [英] Conflicting Definitions in Pattern Matching

查看:51
本文介绍了模式匹配中的定义冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始学习Haskell,并且在2-adic类型课程中遇到了一个问题.这是重要的代码:

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

编译器(GHC 6.12.1)现在抱怨碰撞"的定义冲突

The compiler (GHC 6.12.1) now complains about Conflicting definitions for 'collides'

我不知道,定义如何冲突,对吗?

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

谢谢!

推荐答案

最可能的罪魁祸首是您"..."中某处的布局错误,该错误导致两条 collides 行被分隔为两个单独的块.'collides'的定义冲突意味着在同一范围内有两个不同的位置定义了 collides .这两行要么以某种方式被打断,以便编译器将其视为单独,要么在"..."部分出现错误,以某种方式在一个作用域中两次定义了 collides .

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.

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

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 = ...

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

This is not allowed either, because it (again) defines the same name (foo) twice.

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

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.

在布局敏感的语言中,通常只在代码中使用空格,或者至少要确保编辑器的制表符使用正确数量的空格,这是一个好主意.对于Haskell,该值为8.

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.

这篇关于模式匹配中的定义冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆