在 Haskell 中,为什么你不在 do-block 中使用 'in' 和 'let',但你必须不然呢?
例如,在下面有些人为的例子中:
afunc :: Int -> Int
afunc a =
let x = 9 in
a * x
amfunc :: IO Int -> IO Int
amfunc a = do
let x = 9
a' <- a
return (a' * x)
这是一个很容易记住的规则,但我就是不明白它的原因。
最佳答案
您正在提供表达式来定义 afunc
和 amfunc
. let 表达式和 do block 都是表达式。然而,虽然 let-expression 引入了一个新的绑定(bind),该绑定(bind)在 'in' 关键字之后给出的表达式的范围内,但 do-block 不是由表达式组成的:它是一个语句序列。 do-block 中有三种形式的语句:
x
的计算,如x <- getChar
putStrLn "hello"
let x = 3 + 5
let-statement 引入了一个新的绑定(bind),就像 let-expressions 一样。这个新绑定(bind)的范围扩展到 do-block 中的所有剩余语句。
简而言之,let 表达式中“in”之后的是一个表达式,而 let 表达式之后的是一系列语句。我当然可以使用 let 表达式来表达对特定语句的计算,但是绑定(bind)的范围不会超出该语句到后面的语句。考虑:
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)
工作正常。
关于haskell - 'in' 关键字是怎么回事?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11674892/