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 计算执行。所以letIO 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“让”——它有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章

random.seed():它有啥作用?

***service.builder.addAddress - 它有啥作用?

带有 () 的 C 对象 - 它有啥作用? [复制]

Amazon ELB 自动运行状况检查有啥作用,它有啥期望?

CDATA 到底是啥,它有啥作用?

Visual Studio 中的 TestContext - 它有啥作用?