Take the 2-minute tour ×

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

So far as I can tell, "let" (without "in") is not part of the Haskell language per se, and on the other hand, it doesn't appear to be a GHCI command either, as it's not prefixed by colon.


share|improve this question
add comment

4 Answers

up vote 18 down vote accepted

While programming in GHCi, you're like programming in IO monad with do syntax, so for example you can directly call a function with type of IO a, 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
share|improve this answer
Its not just IO () but any IO action of type IO a. –  Satvik Dec 27 '12 at 9:49
OK, that makes sense, and relates GHCi let to Haskell let... in do. –  gwideman Dec 27 '12 at 10:14
add comment

Read the docs.

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.

share|improve this answer
Thanks for pointing to the docs, I hadn't found that. As a side comment, that doc is rather disappointing, since its explanation of let is sort of premised on understanding monads. New users encounter let almost immediately as it's frequently presented in tutorials on beginning Haskell concepts, yet it doesn't work if copied to a haskell source file, and explanations assuming understanding of monads are not too useful. Nonetheless, with the collection of answers here I at least see how these features fit together. –  gwideman Dec 27 '12 at 10:23
@gwideman Yeah, I understand that. You can not directly copy what you write as ghci statements in a hs file and expect them to work. Well you can ofcourse do main = do <your ghci statements>. It might not work always as expected as ghci prints the output of a statement by using its Show instance. –  Satvik Dec 27 '12 at 13:02
add comment

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.

share|improve this answer
I'm pretty sure I don't understand all of that at this stage, but it is very useful to see the degree to which one should not learn from GHCi :-). Thanks! –  gwideman Dec 28 '12 at 12:56
add comment

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
       {- ... etc. -}

translates to:

translated4 =
    let val1 = expr1
        val2 = expr2
        {- ... etc. -}
        valN = exprN
    in do act1
          {- ... etc. -}
share|improve this answer
OK, this makes a lot of sense. –  gwideman Dec 27 '12 at 10:14
add comment

Your Answer


