2010-07-19 13 views
4
parserChar :: Char -> Parser Char 
parserChar c = Parser ch where 
    ch d = case dvChar d of 
     Parsed c dp -> Parsed c dp 
     _ -> NoParse 

La fonction ci-dessus est censé prendre un char c et retourner un parseur qui ne correspond c. La fonction dvChar d va renvoyer Parsed char dp ou NoParse (où char est le caractère suivant dans la chaîne). Ainsi, j'avais espéré que Parsed c dp ne correspondrait qu'à un résultat dans lequel char==c, mais ce qui se passe actuellement, c'est que l'analyseur renvoyé par cette fonction correspond à n'importe quel caractère (même si c semble être lié à un char particulier, en tant qu'argument de fonction).Motif correspondant pour l'égalité

La fonction suivante fonctionne correctement:

parserChar :: Char -> Parser Char 
parserChar c = Parser ch where 
    ch d = case dvChar d of 
     Parsed char dp -> if char == c then Parsed char dp else NoParse 
     _ -> NoParse 

codage manuellement l'analyseur pour analyser la lettre 'a' fonctionne également correctement, dans ce

case dvChar d of 
    Parsed 'a' dp -> Parsed 'a' dp 
    _ -> NoParse 

ne fera que matcher si le personnage était 'a'.

Alors qu'est-ce qui donne? Pouvez-vous seulement faire correspondre des littéraux dans un modèle comme celui-ci (par exemple, malgré le fait que Char est dans la classe Eq, le if char==c (..) doit encore être codé manuellement), ou est-ce que je fais quelque chose de mal?

+0

Par ailleurs, la règle « que les constructeurs match » est certainement une bonne chose, parce que sinon l'importation d'une nouvelle définition de niveau supérieur (disons) pourrait grandement changer la sémantique d'un morceau de code! –

Répondre

7

Oui, vous ne pouvez associer que des littéraux. En fait, une meilleure façon d'y penser est que vous ne pouvez faire correspondre que des constructeurs, et il arrive que Int, Char, String & co. tous ont des constructeurs littéraux.

Notez que vous pouvez également mélanger cas et les gardes et l'écrire comme (de mémoire):

parserChar :: Char -> Parser Char 
parserChar c = Parser ch where 
    ch d = case dvChar d of 
     Parsed char dp | char == c -> Parsed char dp 
     _ -> NoParse 
Questions connexes