GHCi “let” — what does it do?

后端 未结 4 1875
囚心锁ツ
囚心锁ツ 2020-12-05 07:05

I\'d appreciate if someone could point to docs on what "let" does in GHCi, or failing that, explain it convincingly.

So far as I can tell, "let" (

相关标签:
4条回答
  • 2020-12-05 07:29

    For more down-to-the-code details, this comment in TcRnDriver.lhs might be enlighting:

    --------------------------------------------------------------------------
                    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
    

    So a command at the GHCi prompt can have up to three effects: Some code is evaluated, some things are printed, and some variable names are bound. Your case (the first one in the comment) binds variables, but does not print.

    The syntax does resemble the do-notation, so @sinan’s answer is somewhat right, but it is not really what is happening under the hood – otherwise, for example, nothing would ever be printed.

    0 讨论(0)
  • 2020-12-05 07:39

    GHCI commands are executed in the IO monad and uses do syntax, so the desugaring rules apply. From Real World Haskell

    doNotation4 =
        do let val1 = expr1
               val2 = expr2
               {- ... etc. -}
               valN = exprN
           act1
           act2
           {- ... etc. -}
           actN
    

    translates to:

    translated4 =
        let val1 = expr1
            val2 = expr2
            {- ... etc. -}
            valN = exprN
        in do act1
              act2
              {- ... etc. -}
              actN
    
    0 讨论(0)
  • 2020-12-05 07:47

    Here's the relevant part of the documentation.

    GHCI statements are executed as IO computation. So let is same as what you have inside an IO monad where you bind non-IO expression using let.

    0 讨论(0)
  • 2020-12-05 07:48

    While programming in GHCi, you're like programming in the IO monad with do syntax, so for example you can directly execute an IO action, or use monadic bind syntax like r <- someIOFun.

    let is also a part of do so you can also use this. I think it's being desugared into let .. in <rest of the computation>, so for example when you do this:

    ghci> let a = 1
    ghci> someFun
    ghci> someFun2
    

    It's like:

    let a = 1 in
    do someFun
       someFun2
    
    0 讨论(0)
提交回复
热议问题