2017-09-02 54 views
0

我想用一些let语句定义一个函数,但是我一直收到一个错误parse error on input 'let'。我对Haskell还是个新手,所以我实际上看不出是什么导致了这个问题。用多个let块输入'let'解析错误

这里是我的功能:

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 

我不会解释什么功能是应该做的,因为这是风马牛不相及的问题,我的主要问题是,有第一let解析错误声明,我不知道为什么。

+1

其他人已经回答了'let' ...'in'和'where'这里的区别。但是至于缩进,一个好的经验法则是,如果你只是在布局关键字(比如'do','let')之后换行+缩进,你不会陷入困境(并且不需要做很多事情) ,“哪里”,“案例”......“等等。 –

回答

2

问题在于,您在使用函数后定义了let函数,但let仅用于相反目的。

您可能需要阅读Let vs. Where文章,因为你可以在这里使用where

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 

或者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) 

或者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应该在形式为

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

所以你的情况,是这样的:(里面有do-expressions一个使用let不需要in,但这是特殊的)

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) 

或者,附加声明可以在绑定的可选where之内。

myFunc :: ([String], Int) -> (Int, Int, Int) -> ([String], Int) 
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