使用Haskell的时候,常常混淆let...in 和 let,直到最近仔细一琢模发现在Monad里面似乎从来没用过let...in,想知道这两者的具体区分,于是在Stackoverflow上找到了一个非常好的回答,贴在这里做记录:
总结一句话,在do notation也就是Monad和list comprehension中单独使用let
,在其他所有时候都使用let...in
let...in用法
let variable = expression in expression
如
> (let x = 2 in x*2) + 3
7
单独let用法
do statements
let variable = expression
statements
注意此时的statements要和let对齐
或者
> [(x, y) | x <- [1..3], let y = 2*x]
[(1,2),(2,4),(3,6)]
至于为什么在后两者情况中不用in,我不太认可最高票回答,感觉和expression和stastement关系不大。因为在Haskell中就没有statement的概念,后两者不需要in是因为do-notation中本身就已经自带了in,正如后面几个回答说的,第二种情况do可以改写成
do statements
let variable = expression
in do
statements
而根据Haskell report,list comprehension中的let可以改写为
[ e | let decls, Q ] = let decls in [ e | Q ]
当然,此时let 的scope只包含let右边的Q,如果let之前加入还有expression P,
,那P
中的变量 是不能访问到let中的binding的