Tneuktippa
Tneuktippa

Reputation: 1695

How do I use a let within a do block in ghci?

I'm trying to create a do block interactively in ghci. As long as I don't define a variable with in block, it's fine:

Prelude>let a = do putStrLn "test"; putStrLn "other test"
Prelude>

but I can't figure out how to define a let construction in the do block interactively without getting a parse error:

Prelude> let a = do let b = 5; putStrLn $ show b

<interactive>:2:40:
    parse error (possibly incorrect indentation or mismatched brackets)

Obviously

let a = do
     let b = 5
     putStrLn $ show b

is entirely fine in a Haskell source file. I'm just having trouble figuring out how to translate that to ghci.

Upvotes: 12

Views: 4389

Answers (4)

easoncxz
easoncxz

Reputation: 261

I landed here because I had the same question, but yatima2975's answer reminded me of how each let-block can have multiple bindings, so I tried the below and indeed it works.

$ ghci
GHCi, version 8.8.3: https://www.haskell.org/ghc/  :? for help
Prelude> do { let { x = 1; y = 2 }; putStrLn (show (x, y)) }
(1,2)

Upvotes: 1

onemouth
onemouth

Reputation: 2277

:help

 <statement>                 evaluate/run <statement>    
:{\n ..lines.. \n:}\n        multiline command

You can type :{ to start a multiline command, and type :} to end it.

So just do

 Prelude> :{
 Prelude| let a = do
 Prelude|     let b=5
 Prelude|     putStrLn $ show b
 Prelude| 
 Prelude| :} 

Be careful with layout (indentation/whitespace). Otherwise you can get parse errors in apparently correct code.

For example the following will NOT work because the indentation isn't deep enough:

Prelude> :{
Prelude| let a = do
Prelude|    let b=5
Prelude|    putStrLn $ show b
Prelude| 
Prelude| :}

It will lead to a parse error like this:

<interactive>:50:4: parse error on input ‘let’

Upvotes: 13

Chris Taylor
Chris Taylor

Reputation: 47382

I would have thought that putting braces in would be fine, but this doesn't parse:

ghci> let a = do {let b = 5; putStrLn (show b)}

You can always take the multiline approach, which does work:

ghci> :{
ghci| let a = do let b = 5
ghci|            putStrLn $ show b
ghci| :} 

Upvotes: 1

yatima2975
yatima2975

Reputation: 6610

Try this:

let a = do let { b = 5 } ; print b 

The let block can contain multiple declarations so you have to tell GHCi when they're done - that's what the brackets are for in this line.

By the way, you can use print for putStrLn . show.

Upvotes: 15

Related Questions