2010-10-23 4 views
1

Je viens de commencer à apprendre Haskell et j'ai rencontré un problème dans les classes de type 2-adic. Voici le code important:Conflicting Definitions dans Pattern Matching

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

Le compilateur (GHC 6.12.1) se plaint maintenant de Conflicting definitions for 'collides'

Je ne vois pas comment les définitions seraient en conflit, pensez-vous?

Merci!

+1

Impossible de reproduire. En remplaçant le '...' par false et en activant MultiParamTypeClasses, votre code compile bien pour moi. – sepp2k

+0

@ sepp2k, wow j'ai fait exactement la même chose et posté ma réponse 1 minute après vous! – HaskellElephant

+1

Pour moi, ce n'est pas mais compile bien. Des drapeaux supplémentaires sont-ils séparés de 'MultiParamTypeClasses'? Essayez de supprimer ce qu'il y a dans le '...' et faites fonctionner les types. – Dario

Répondre

3

Le coupable le plus probable est une erreur de disposition quelque part dans votre "..." qui provoque la séparation des deux lignes collides en deux blocs distincts. Conflicting definitions for 'collides' signifie qu'il existe deux emplacements différents dans la même étendue qui définissent collides. D'une manière ou d'une autre ces deux lignes sont interrompues de sorte que le compilateur les voit comme séparées, ou il y a une erreur dans la partie "..." qui définit en quelque sorte collides deux fois dans une portée.

Il existe deux façons principales de déclencher l'erreur. Tout d'abord, deux liaisons dans la même définition de fonction peuvent essayer de lier la même variable, comme dans foo x x = .... Ce n'est pas autorisé, car il définit deux fois x.

L'autre (qui est celui que je soupçonne d'appliquer dans votre code) est quand deux parties de la même définition sont "interrompues" par une autre définition. Le compilateur voit cela comme deux définitions distinctes. Par exemple:

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

Ce n'est pas permis non plus, car il (encore une fois) définit le même nom (foo) deux fois.

L'interruption peut ne pas être évidente, en particulier dans les cas où vous mélangez accidentellement des onglets et des espaces (et votre éditeur utilise autre chose que les 8 onglets par espace qu'Haskell assume). Il peut apparaître dans votre éditeur comme étant une ligne indentée dans une clause where mais en raison des différences de largeur de tabulation, le compilateur le voit aligné avec foo, faisant de la seconde foo une autre définition en conflit avec la première.

Il est généralement considéré comme une bonne idée dans les langages sensibles à la disposition d'utiliser uniquement des espaces dans votre code, ou tout au moins de vous assurer que votre éditeur utilise le bon nombre d'espaces pour ses onglets. Pour Haskell, c'est 8.

+0

Merci! Cela a aidé :) – zombiecalypse