我很欣赏有人可以指出关于GHCi中“let”做什么的文档,或者说失败,有说服力地解释它:-)。
据我所知,“let”(没有“in”)本身不是Haskell语言的一部分,另一方面,它似乎也不是GHCI命令,因为它不是以冒号为前缀。
答案 0 :(得分:31)
在GHCi中编程时,您需要使用do
语法在IO monad中进行编程,例如,您可以直接执行IO
操作,或使用monadic绑定语法,如{{ 1}}。
r <- someIOFun
也是let
的一部分,因此您也可以使用它。我认为它正在被do
贬低,所以例如当你这样做时:
let .. in <rest of the computation>
就像:
ghci> let a = 1
ghci> someFun
ghci> someFun2
答案 1 :(得分:11)
以下是documentation的相关部分。
GHCI语句作为IO计算执行。所以let
与使用IO
绑定非IO表达式的let
monad中的内容相同。
答案 2 :(得分:9)
有关详细信息的详细信息,TcRnDriver.lhs中的此评论可能会有所启发:
--------------------------------------------------------------------------
Typechecking Stmts in GHCi
Here is the grand plan, implemented in tcUserStmt
What you type The IO [HValue] that hscStmt returns
------------- ------------------------------------
let pat = expr ==> let pat = expr in return [coerce HVal x, coerce HVal y, ...]
bindings: [x,y,...]
pat <- expr ==> expr >>= \ pat -> return [coerce HVal x, coerce HVal y, ...]
bindings: [x,y,...]
expr (of IO type) ==> expr >>= \ it -> return [coerce HVal it]
[NB: result not printed] bindings: [it]
expr (of non-IO type, ==> let it = expr in print it >> return [coerce HVal it]
result showable) bindings: [it]
expr (of non-IO type,
result not showable) ==> error
因此,GHCi提示符下的命令最多可以产生三种效果:评估某些代码,打印一些代码,并绑定一些变量名称。您的案例(评论中的第一个案例)会绑定变量,但不会打印。
语法与do-notation类似,所以@sinan的答案有点正确,但它并不是真正发生在幕后的事情 - 否则,例如,什么都不会被打印出来。
答案 3 :(得分:4)
GHCI命令在IO monad中执行并使用do语法,因此适用于desugaring规则。来自Real World Haskell
doNotation4 =
do let val1 = expr1
val2 = expr2
{- ... etc. -}
valN = exprN
act1
act2
{- ... etc. -}
actN
转换为:
translated4 =
let val1 = expr1
val2 = expr2
{- ... etc. -}
valN = exprN
in do act1
act2
{- ... etc. -}
actN