GHCi“让”——它有啥作用?
Posted
技术标签:
【中文标题】GHCi“让”——它有啥作用?【英文标题】:GHCi "let" -- what does it do?GHCi“让”——它有什么作用? 【发布时间】:2012-12-12 16:34:42 【问题描述】:如果有人能指出有关“let”在 GHCi 中的作用的文档,我将不胜感激,或者如果失败,请令人信服地解释它。
据我所知,“let”(没有“in”)本身不是 Haskell 语言的一部分,另一方面,它似乎也不是 GHCi 命令,因为它不是以冒号为前缀。
【问题讨论】:
简答:let
(没有in
)是 Haskell 语言的一部分,在 do
块内时(并且在 GHCi 中编写类似于在IO
monad)。
【参考方案1】:
在 GHCi 中编程时,您就像使用 do
语法在 IO monad 中编程一样,因此例如您可以直接执行 IO
操作,或者使用像 r <- someIOFun
这样的 monadic 绑定语法。
let
也是do
的一部分,所以你也可以使用它。我认为它被脱糖成let .. in <rest of the computation>
,所以例如当你这样做时:
ghci> let a = 1
ghci> someFun
ghci> someFun2
就像:
let a = 1 in
do someFun
someFun2
【讨论】:
它不仅仅是IO ()
,而是IO a
类型的任何IO
动作。
好的,这是有道理的,并将 GHCi let 与 Haskell let... 联系起来。
let
without in
允许在 do-block 中使用,并且不等同于您给出的示例(参见***.com/questions/8274650/…)
这个脱糖词让我有点吃惊。认为这是des-u-gared。不知道是什么意思。【参考方案2】:
这是documentation的相关部分。
GHCI 语句作为 IO 计算执行。所以let
与IO
monad 中的内容相同,在该monad 中使用let
绑定非IO 表达式。
【讨论】:
感谢您指向文档,我没有找到。作为旁注,该文档相当令人失望,因为它对 let 的解释有点以理解单子为前提。新用户几乎立即会遇到 let,因为它经常出现在有关 Haskell 入门概念的教程中,但如果复制到 haskell 源文件,它就不起作用,并且假设理解 monad 的解释不太有用。尽管如此,通过这里收集的答案,我至少看到了这些功能是如何组合在一起的。 @gwideman 是的,我明白这一点。您不能直接将您编写的内容作为 ghci 语句复制到 hs 文件中并期望它们正常工作。那么你当然可以做main = do <your ghci statements>
。它可能并不总是像预期的那样工作,因为 ghci 使用其 Show
实例打印语句的输出。【参考方案3】:
要了解更多代码细节,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 的回答有些正确,但实际上并不是幕后发生的事情——否则,例如,什么都不会被打印出来。
【讨论】:
我很确定在这个阶段我还没有完全理解这些,但是看看人们不应该从 GHCi 学习到什么程度是非常有用的 :-)。谢谢!【参考方案4】:GHCI 命令在 IO monad 中执行并使用 do 语法,因此适用脱糖规则。来自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
【讨论】:
好吧,这很有意义。以上是关于GHCi“让”——它有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章
***service.builder.addAddress - 它有啥作用?