2016-07-07 15 views
1

Ich weiß, das funktioniert:HASKELL --- Mit "let" innerhalb einer "do" Syntax in GHCI

do name <- getLine; let nameTag = "Hello, my name is " ++ name in putStrLn nameTag 

Neben diesem Stück Code beim Laden in GHCI:

hey = do 
    name <- getLine 
    let nameTag = "Hello, my name is " ++ name 
    putStrLn nameTag 

aber das funktioniert nicht:

do name <- getLine; let nameTag = "Hello, my name is " ++ name; putStrLn nameTag 

geben Sie die folgende Fehlermeldung:

<interactive>:142:82: 
    parse error (possibly incorrect indentation or mismatched brackets) 

Warum funktioniert es nicht? Kann ich es zum Laufen bringen? Wenn ja, wie?

+1

Bitte formatieren Sie Ihren Code. –

+1

Das Problem ist, dass der Parser denkt, dass die Struktur Ihres Codes 'let {nameTag = ...; putStrLn nameTag} 'wo erwartet eine Zuweisung statt' putStrLn nameTag'. – Bakuriu

Antwort

5

Ja, können Sie Klammern um die let-Bindung (en) verwenden, um die Analyse eindeutig zu machen:

do name <- getLine; let { nameTag = "Hello, my name is " ++ name }; putStrLn nameTag 
+0

Danke! Ich habe versucht, Klammern zu verwenden, aber das hat nicht funktioniert. Was ist der grundlegende Unterschied zwischen geschweiften Klammern und Klammern in Haskell? –

+1

@ RafałPłaszczyk Klammern dienen zum Abgrenzen von Teilausdrücken. Curly Brackets dienen zur Unterscheidung der Sprachsyntax. (Oh, und notiere Syntax ...) – MathematicalOrchid

+1

@ RafałPłaszczyk Sie haben wahrscheinlich bemerkt, dass Haskell indentationsempfindlich ist. Klammern erlauben es grundsätzlich, alles in eine Zeile zu schreiben und Blöcke ('do, let, wo, case of') auf derselben Einrückungsebene wie' {entry1; entry2; ...} 'zu schreiben. Normalerweise nicht erforderlich, außer in GHCi. In vielen Fällen sind nur ';' ausreichend und Klammern können weggelassen werden. – chi

4

Um die Antwort von McKenna zu ergänzen, kann der Fehler wie folgt erklärt werden: Vergleichen Sie diese beiden Zeilen

siehe
do name <- getLine; let name1 = "One"; putStrLn name1 
do name <- getLine; let name1 = "One"; name2 = "Two"; putStrLn name1 

kann ein menschlicher Leser, dass sie tatsächlich bedeuten,

do { name <- getLine; let { name1 = "One" } ; putStrLn name1 } 
do { name <- getLine; let { name1 = "One"; name2 = "Two" }; putStrLn name1 } 

aber der Parser ist nicht das ist schlau. Wenn der Haskell-Parser sieht den gemeinsamen Codeabschnitt

do name <- getLine; let name1 = "One"; 
            --^-- 

es muss entscheiden, ob die letzten ; zur do Ebene gehört (wie im ersten Fall oben) oder in den let Ebene (zweiten Fall). Es stellt sich heraus, dass es let wählt und später fehlschlägt.