if-then-else inside a "do"

Fergus Henderson fjh@cs.mu.oz.au
Wed, 30 Jan 2002 15:28:34 +1100


On 29-Jan-2002, Andre W B Furtado <awfurtado@uol.com.br> wrote:
> In the following code, will "other things" be executed or the "return ()"
> will end function f? I guess the answer is yes ("other things" WILL be
> executed anyway), but I'd like to understand why won't the "return ()" be
> the [state change/result produced] created by f.
> 
> f :: IO ()
> f = do
>     -- lots of things
>     if False then doSomething else (return ())
>     -- other things

The "if" here is actually irrelevant to the question.
The same issue arises for the following function:

	g :: IO ()
	g = do
		return ()
		-- other things

Unlike in C, "return" does not terminate execution of the enclosing
function.  Rather, "return ()" is a just a computation of type IO ()
which has no effect and which returns the value "()".  By "returning"
here I mean returning from that computation, not returning from the
enclosing function.

When you have two actions in sequence in a "do" like this,

	do
		action1
		action2

the meaning of the `do' expression is an action whose effect is to
execute the first action (action1), throw away the return value,
and then execute the second action (action2), and whose return
value is the return value form the section action.
So
	do
		return ()
		action2

is an action whose effect is to first do nothing, throwing away the return
value "()", and then do action2 -- in other words this do expresion as
a whole is exactly equivalent to action2.

Compare this example with one where you don't throw away the return value:

	h :: IO ()
	h = do
		x <- return ()
		-- other things

This example is the same as

	h :: IO ()
	h = do
		let x = ()
		-- other things

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.