Yet Another Monad Tutorial

Wolfgang Jeltsch
Tue, 12 Aug 2003 23:15:30 +0200

On Tuesday, 2003-08-12, 18:20, CEST, Jeff Newbern wrote:
> [...]

> In the section "No Way Out":
> ----------
> The IO monad is a familiar example of a one-way monad in Haskell. Because
> you can't escape from the IO monad, it is impossible to write a function
> that does a computation in the IO monad but returns a non-monadic value. Not
> only are functions of the type IO a -> a impossible to create, but any
> function whose result type does not contain the IO type constructor is
> guaranteed not to use the IO monad. Other monads, such as List and Maybe, do
> allow values out of the monad. So it is possible to write non-monadic
> functions that internally do computations in those monads. The one-way
> nature of the IO monad also has consequences when combining monads, a topic
> that is discussed in part III.

This sounds rather vague to me. I don't like the formulation of a function 
doing a computation in the IO monad because execution of I/O actions is done 
separated from function application and evaluation (although interleaved with 
it because of lazy evaluation etc.). Tell me, if I'm pedantic.

By the way, it *is* possible to create a function of type IO a -> a:
    f :: IO a -> a
    f = const undefined
That's why in my last mail I spoke about *useful* functions which are 
implementable for State (but not for IO).

> [...]

> The functions exported from the IO module do not perform I/O themselves.

This is what I wanted to say above.

> They return I/O actions, which describe an I/O operation to be performed.
> The I/O actions are combined within the IO monad (in a purely functional
> manner) to create more complex I/O actions, resulting in the final I/O
> action that is the main value of the program.

Very good!

> The result of the Haskell compiler is an executable function incorporating
> the main I/O action. Executing the program "applies" this ultimate I/O
> action to the outside world to produce a new state of the world.

I wouldn't talk about functions and function applications here because what 
you mean are not Haskell functions and applications of them. You can think of 
an I/O action being a function conceptually and the execution of it being a 
function application but using these terms here will most likely confuse 

> [...]