2017-09-02 2 views
0

Ich versuche, eine Funktion mit einer Anzahl von let-Anweisungen zu definieren, aber ich bekomme immer einen Fehler parse error on input 'let'. Ich bin immer noch neu in Haskell, so dass ich nicht wirklich sehen kann, was dieses Problem verursacht.parse Fehler bei Eingabe 'let' mit mehreren lassen Blöcke

Hier ist meine Funktion:

myFunc :: ([String], Int) -> (Int, Int, Int) -> ([String], Int) 
nextGuess (prev_string, prev_int) (a1, a2, a3) = (new_string, new_int) 
    let new_int_1 = if a3 - a1 < 0 
     then prev_int 
     else (filter (myPred1 a3 prev_string) prev_int) 
    let new_int_2 = if a2 - a1 < 0 
     then new_int_1 
     else (filter (myPred2 a2 prev_string) new_int_1) 
    new_int = filter (myPred3 a1 prev_string) new_int_2 

Ich werde nicht erklären, was die Funktion tun soll, weil das auf die Frage irrelevant ist, ist mein Hauptproblem, dass es auf den ersten let ein Parse-Fehler Aussage und ich weiß nicht warum.

+1

Andere haben bereits über den Unterschied zwischen 'Let' ...' In' und 'Where' hier geantwortet. Aber wie beim Einrücken, eine gute Faustregel ist, dass Sie nicht in Schwierigkeiten geraten (und müssen nicht fiddly Ausrichtung der Dinge tun), wenn Sie nur Newline + Einzug nach Layout-Keywords wie "do", "Let" , 'wo',' Fall' ... 'von' und so weiter. –

Antwort

2

Das Problem ist, dass Sie Funktionen nach let nach der Verwendung der Funktionen definieren, aber let ist für den entgegengesetzten Zweck.

Sie möchten vielleicht Let vs. Where Artikel lesen, weil Sie where hier verwenden können:

nextGuess (prev_string, prev_int) (a1, a2, a3) = (new_string, new_int) 
    where 
     new_int_1 = if a3 - a1 < 0 
     then prev_int 
     else (filter (myPred1 a3 prev_string) prev_int) 
     new_int_2 = if a2 - a1 < 0 
     then new_int_1 
     else (filter (myPred2 a2 prev_string) new_int_1) 
     new_int = filter (myPred3 a1 prev_string) new_int_2 

Oder let in:

nextGuess (prev_string, prev_int) (a1, a2, a3) = 
    let new_int_1 = if a3 - a1 < 0 
      then prev_int 
      else (filter (myPred1 a3 prev_string) prev_int) 
     new_int_2 = if a2 - a1 < 0 
      then new_int_1 
      else (filter (myPred2 a2 prev_string) new_int_1) 
     new_int = filter (myPred3 a1 prev_string) new_int_2 
     in 
      (new_string, new_int) 

Oder do notation:

nextGuess (prev_string, prev_int) (a1, a2, a3) = do 
    let new_int_1 = if a3 - a1 < 0 
      then prev_int 
      else (filter (myPred1 a3 prev_string) prev_int) 
    let new_int_2 = if a2 - a1 < 0 
      then new_int_1 
      else (filter (myPred2 a2 prev_string) new_int_1) 
    let new_int = filter (myPred3 a1 prev_string) new_int_2 
    (new_string, new_int) 
1

let-expressions in sein sollte das Formular

let pattern_1 = expression_1 
    pattern_2 = expression_2 
    ... 
in final_expression 

so in Ihrem Fall, so etwas wie folgt aus: (. Es ist eine Verwendung von let innerhalb do-expressions, die nicht in erfordert, aber das ist etwas Besonderes)

myFunc :: ([String], Int) -> (Int, Int, Int) -> ([String], Int) 
nextGuess (prev_string, prev_int) (a1, a2, a3) = 
    let new_int_1 = if a3 - a1 < 0 
      then prev_int 
      else (filter (myPred1 a3 prev_string) prev_int) 
     new_int_2 = if a2 - a1 < 0 
      then new_int_1 
      else (filter (myPred2 a2 prev_string) new_int_1) 
     new_int = filter (myPred3 a1 prev_string) new_int_2 
    in (new_string, new_int) 

Alternativ Die zusätzlichen Deklarationen können innerhalb des optionalen where der Bindung liegen.