解析输入'let'有多个let块

时间:2017-09-02 04:41:39

标签: haskell syntax

我正在尝试使用许多let语句定义一个函数,但我一直收到错误parse error on input 'let'。我还是Haskell的新手,所以我实际上无法看到导致这个问题的原因。

这是我的功能:

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语句中存在解析错误而我没有&#39;我知道为什么。

2 个答案:

答案 0 :(得分: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 :(得分:1)

let-expressions应采用

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

所以在你的情况下,像这样:

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)

(在do-expressions内使用let不需要in,但这很特别。)

或者,附加声明可以在绑定的可选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