2010-08-09 13 views
6

SpécificationsHaskell Erreur: parse error sur l'entrée `= »

GHC 6.12.1

Mac OS X 10.6.4 x64

MacBook Pro

Problème

J'ai des problèmes pour utiliser la syntaxe let. Le code suivant refuse de compiler:

module Main where 

main = let x = 1 
     y = 2 
     z = 3 
    in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z 

J'ai essayé tabuler dans y = 2 et z = 3 encore plus. Pas de dé.

(Solutions) indésirables

La seule façon que j'ai obtenu le code à compiler est soit

  1. Remplacement des onglets durs avec des espaces.
  2. Remplacement de la clause let par une clause where.
+2

jamais utiliser les onglets avec haskell, utilisez toujours des espaces.Les onglets en haskell sont définis comme étant de 8 espaces, ce qui est beaucoup plus que ce à quoi les gens s'attendent/définissent leur éditeur, donc il est toujours conseillé d'utiliser des espaces. Tout éditeur décent vous permettra de faire des onglets produire des espaces. – Axman6

+0

J'ai trouvé cela une excellente aide visuelle, et un excellent guide sur le sujet en général: [http://echo.rsmw.net/n00bfaq.html#visualaid](http://echo.rsmw.net/n00bfaq.html# visualaid) – Brandon

Répondre

15

Saizan sur #haskell explique que les missions dans une expression let doivent aligner, ne se laisser. Tant que les devoirs s'alignent, vous pouvez utiliser des onglets durs ou des onglets mous.

code correct:

module Main where 

main = let 
     x = 1 
     y = 2 
     z = 3 
    in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z 
+1

J'ai trouvé que les liaisons (x, y, z) doivent s'aligner verticalement par opposition aux signes d'affectation (=) des 3 liaisons qui peuvent être difficiles à voir avec cet exemple. – ssanj

3

Indenter chaque déclaration dans le let-block au même degré. Une bonne forme consiste également à indenter le 'in' et le 'let' au même niveau. Par exemple, ..

main = let x = 1 
      y = 2 
      z = 3 
     in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z 
+0

Comment faire ceci avec des onglets durs? – mcandre

+9

Pourquoi voulez-vous utiliser des onglets durs? Ils sont modérément bien dans les langues qui n'utilisent pas l'indentation pour le sens, mais ils vont juste rendre votre vie difficile dans des langages comme Haskell ou Python. Comme ils sont en ce moment. – jrockway

+4

Python gère parfaitement les onglets durs. Une fois, j'ai eu du mal à coder Python via un client Web SSH car le client ne pouvait pas insérer d'onglets. J'utilise des onglets durs parce que je déteste avoir à réindenter de force les codes des autres à ma largeur d'indentation préférée. Les onglets durs n'ont pas ce problème, puisque les éditeurs de texte peuvent afficher les onglets durs à n'importe quelle largeur. – mcandre

11

Vous ne pouvez pas contrôler le retrait correctement avec des onglets, car la taille d'un onglet est non défini.

Par conséquent, n'utilisez pas d'onglets dans Haskell. Ils sont méchants.

+3

Ou, pour les objets qui doivent avoir un niveau d'indentation différent, utilisez une nouvelle ligne. Par exemple, mettez 'let' sur une ligne et' x = 1' sur la ligne suivante. Ensuite, les onglets ne posent aucun problème. – yfeldblum

+0

Neil, je ne suis pas d'accord (voir ma réponse). Un gars sur #haskell a été capable de m'aider à construire une version compilable, à onglets. En fait, la réponse du juge est correcte. – mcandre

+0

J'ai appris ma leçon à la dure! Je savais que les onglets étaient horribles mais toujours utilisés juste parce qu'ils ne m'ont jamais posé de problème auparavant. Si vous êtes comme moi, sauvez-vous un gros mal de tête et suivez ce conseil, maintenant! – MasterMastic

1

Si vous insistez sur les caractères TAB dans votre source, les compiles suivantes:

module Main where 

main = 
    let x = 1 
     y = 2 
     z = 3 
    in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z 

où tous les principaux espaces est un ou deux pattes, et l'espace entre les let et x = 1 est également un onglet. Vu en vi list mode de faire OET et ligne se termine explicitement:

module Main where$ 
$ 
main =$ 
^Ilet^Ix = 1$ 
^I^Iy = 2$ 
^I^Iz = 3$ 
^Iin putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z$

Votre vie sera beaucoup plus simple et votre code plus joli si vous passez à des espaces.

+0

Merci. Je ne pense pas que je veux me souvenir de tabulation entre let et x à chaque fois. En outre, tout code que je publie entraînera probablement des erreurs puisque les lecteurs supposeront qu'il y a un espace ordinaire là-bas. – mcandre

+0

Par conséquent, pourquoi les onglets durs rendent votre code plus difficile à coder et à lire! – adamse

2

Personnellement, je mets virgule à la fin de chaque ligne

module Main where 

main = let x = 1 ; 
      y = 2 ; 
      z = 3 
in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z 
+0

Cela fonctionnera avec le point-virgule, mais je ne l'utiliserai pas puisque la langue fonctionne bien. Juste pour l'indentation, utilisez des espaces à la place des onglets (ou des onglets correctement). – Jaider