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

Chris Kuklewicz haskell at list.mightyreason.com
Thu Aug 17 04:39:36 EDT 2006

Szymon Ząbkiewicz wrote:
> Hi.
> When trying to compilke this code:
> {...}
> 8.if (a == 0) && (b == 0)
> 9.       then do
> 10.             nr1 <- read (prompt "enter 1. number: ")
> 11.             nr2 <- read (prompt "enter 2. number: ")

The nr2 here is not passed to the rest of the do block started on line 9

> 12.       else do
> 13.            let nr1 = a
> 14.                nr2 = b

The nr1 and nr2 in the else block have absolutely nothing to do with the nr1 and 
nr2 from the then block.  The names are the same, but that does not make them 
the same as they could be totally different types.

> {...}
> The compiler tells me thats there's an error on line 10:
> "The last statement in a 'do' construct mesy be an expression"
> Could you tell me how to change it so that the "declaration" of the
> first nr1 and nr2 is still in the "then" block.

The "x <- foo" syntax is not a declaration.

Also, the type of "read" is String->a which is NOT a monad type, so I will fix 
that as well:

One could do this:

(nr1,nr2) <- if (a==0) && (b==0)
                then do a' <- liftM read (prompt "...")
                        b' <- liftM read (prompt "...")
                        return (a',b')
                else return (a,b)

The ghc compiler is usually smart enough to remove the tuple (,) construction 
from the code.

More information about the Haskell-Cafe mailing list