[Haskell-cafe] Last statement in 'do' must be an expression error.

Bulat Ziganshin bulat.ziganshin at gmail.com
Thu Aug 17 05:25:07 EDT 2006

Hello Szymon,

Thursday, August 17, 2006, 12:18:25 PM, you wrote:

>  8.if (a == 0) && (b == 0)
>  9.       then do
> 10.             nr1 <- read (prompt "enter 1. number: ")
> 11.             nr2 <- read (prompt "enter 2. number: ")
> 12.       else do
> 13.            let nr1 = a
> 14.                nr2 = b
> {...}

1. as already said, your nr vars is local to the do blocks. you can't
_assign_ to variables in Haskell, instead you should return
_values_ that will become result of whole "if" expression:

(nr1,nr2) <- if ...
               then do x <- ..
                       y <- ..
                       return (x,y)
                    do return (a,b)

2. as Chris said, "read" is a function (at least 'read' predefined in
std Haskell library), while your 'prompt' should be I/O procedure. you
can't call I/O procedures inside of functions, i.e. that is possible:

function calls function
I/O procedure calls function
I/O procedure calls I/O procedure

and that's impossible:
function calls I/O procedure

So you should assign result of procedure call to "variable" and then call
function on this value:

(nr1,nr2) <- if a==0 && b==0
               then do x <- prompt "enter 1. number: "
                       y <- prompt "enter 2. number: "
                       return (read x, read y)
               else return (a,b)

to be exact, x and y are not variables, but just bound identifiers
like a and b. '<-' is special construct inside of 'do' block that
binds to identifier value returned by I/O procedure call

i've written tutorial on Haskell IO monad. you can try to read it, but
it's more appropriate for intermediate Haskellers who has a good
understanding of pure facilities of the language. but nevertheless try
it - http://haskell.org/haskellwiki/IO_inside . i will be interesting
to hear your opinion and depending on it will become more or less
skeptical about suggesting it to Haskell newcomers fighting with
mysterious IO monad :D

in general, i suggest to learn pure foundations of Haskell such as
lazy evaluation and higher-order functions. after that, learning IO
monad using my tutorial will be as easy as saying "cheese" :)

Best regards,
 Bulat                            mailto:Bulat.Ziganshin at gmail.com

More information about the Haskell-Cafe mailing list