您正在提供表达式来定义afunc
和amfunc
。let 表达式和 do 块都是表达式。然而,虽然 let-expression 引入了一个新的绑定,该绑定在 'in' 关键字之后给出的表达式的范围内,但 do-block 不是由表达式组成的:它是一个statements序列。do-block 中有三种形式的语句:
结果绑定到某个变量的计算x
,如
x <- getChar
结果被忽略的计算,如
putStrLn "hello"
一个 let 语句,如
let x = 3 + 5
let-statement 引入了一个新的绑定,就像 let-expressions 一样。这个新绑定的范围扩展到 do-block 中的所有剩余语句。
简而言之,let 表达式中“in”之后的是一个表达式,而 let 表达式之后的是一系列语句。我当然可以使用 let 表达式来表达对特定语句的计算,但是绑定的范围不会超出该语句而扩展到后面的语句。考虑:
do putStrLn "hello"
let x = 3 + 5 in putStrLn "eight"
putStrLn (show x)
上述代码在 GHC 中导致以下错误消息:
Not in scope: `x'
然而
do putStrLn "hello"
let x = 3 + 5
putStrLn "eight"
putStrLn (show x)
工作正常。