2017-10-06 3 views
2

Quelqu'un peut-il me dire ce qui ne va pas ici? Je ne peux pas comprendre où est l'erreur. Je suis nouveau à haskell, donc je ne connais pas toutes les règles de syntaxe atm.Haskell - Erreur de syntaxe

parseS (s:xs) | all isDigit s = (xs, Lit (read s)) 
      | s == " " = parseS xs 
      | s == "-" = let (remainder, e) = parseS xs in (remainder, Sub e) 
      | s == "+" = (xs'', Sum e e') where 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 

      | s == "*" = (xs'', Mul e e') where  <- parse error on input on this line 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 
+2

S'il vous plaît code postal, des erreurs, des données d'échantillon ou de sortie texte ici en texte brut, pas comme des images qui peuvent être difficiles à lire, ne peut pas être collé pour aider le code de test ou d'utiliser dans les réponses, et sont hostiles à ceux qui utilisent des lecteurs d'écran. Vous pouvez modifier votre question pour ajouter le code dans le corps de votre question. Utilisez le bouton '{}' pour formater tous les blocs de code, ou indentez avec quatre espaces pour le même effet. Nous ne pouvons pas exécuter votre capture d'écran en tant que code. – tadman

+3

Veuillez poster le message d'erreur, verbatim. –

Répondre

2

Voici comment Haskell voit votre code:

parseS (s:xs) 
     | all isDigit s = (xs, Lit (read s)) 
     | s == " " = parseS xs 
     | s == "-" = let (remainder, e) = parseS xs in (remainder, Sub e) 
     | s == "+" = (xs'', Sum e e') 
    where 
    (xs', e) = parseS xs 
    (xs'', e') = parseS xs' 

| s == "*" = (xs'', Mul e e') 
    where 
    (xs', e) = parseS xs 
    (xs'', e') = parseS xs' 

Un bloc where attache à une déclaration, ce qui dans votre cas est toute définition parseS.

La ligne suivante commençant par | est considérée comme le début d'une nouvelle déclaration, qui n'est pas valide car vous ne pouvez pas démarrer une déclaration avec |.

Le correctif est plus facile d'arrêter d'utiliser where pour les liaisons locales et utiliser let au lieu, comme ceci:

  | s == "+" = 
       let 
        (xs', e) = parseS xs 
        (xs'', e') = parseS xs' 
       in 
       (xs'', Sum e e') 

      | s == "*" = 
       let 
        (xs', e) = parseS xs 
        (xs'', e') = parseS xs' 
       in 
       (xs'', Mul e e') 
3

Le problème est que la première clause where est considérée comme la fin de la définition de parseS (s:xs). Vous essayez d'ajouter un autre cas protégé par la suite, mais l'analyseur ne le voit pas comme attaché à la même définition.

Il y a plusieurs façons de résoudre ce problème.

Vous pourrait résoudre ce problème en utilisant un let ... in plutôt pour s == "+"

 | s == "+" = let (xs', e) = parseS xs 
         (xs'', e') = parseS xs 
        in (xs'', Sum e e') 
     | s == "*" = (xs'', Mul e e') where 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 

Mais il y a un moyen plus facile de le faire - il suffit de laisser tomber cette clause where.

 | s == "+" = (xs'', Sum e e') 
     | s == "*" = (xs'', Mul e e') where 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 

Les variables définies dans une clause where sont dans la portée de l'ensemble d'une définition (pour tous les cas de garde), de sorte que votre définition de xs'' peut être réutilisé pour les deux cas.