[Haskell-beginners] clarification on IO

Chaddaï Fouché chaddai.fouche at gmail.com
Sat Feb 28 04:13:49 EST 2009

On Sat, Feb 28, 2009 at 3:50 AM, Michael Easter <codetojoy at gmail.com> wrote:
> Q1: The web page mentions that normal Haskell functions cannot cause
> side-effects, yet later talks about
> side-effects with putStrLn. I assume the key point here that IO actions are,
> by definition, _not_ normal functions?

putStrLn is a perfectly pure function (there is no other kind in
Haskell), it takes a String and return a value of type IO (), this
value is like any other first class object in Haskell and can be
manipulated as thus, the only difference is that this value can be
computed in the context of the IO monad and then have a side-effect.
The value of type IO a are often called actions but they aren't
fundamentally different from other values.

> Q2: Is it true to say that any monadic action could cause side-effects,
> depending on the design of that
> monad? i.e. Does one generalize from the IO monad to (possibly) an arbitrary
> monad? *Musing* This must be true as
> using State must surely be considered a side-effect.

"Side-effect" isn't really appropriate in my opinion, since everything
is still perfectly pure (except in IO) and the "effects" one obtain by
using a monad are perfectly determined by the nature of the monad.

> Q3: The web page mentions IO as being a baton, or token, that is used to
> thread/order the actions. Is true
> that this is merely one simple perspective, with respect to order of
> evaluation? This is hard to articulate,
> but it seems to me that "in the IO monad" there is a large subsystem of
> (inaccessible) state, machinery, etc.
> Is it really a token?

This "token" is an useful concept to understand how the IO monad
works, indeed that is how it is encoded in GHC where the IO monad is
just a variant of the ST monad with a special type for the state :
RealWorld. Of course the primitives used in the IO monad can't be
written in pure Haskell.

> Q4: Is the following idea accurate: a Haskell program is partitioned into 2
> spaces. One is a sequence
> of IO actions; the other is a space of pure functions and 'normal' Haskell
> operations.  The execution of a
> program begins with the main :: IO () action and, effectively, crosses from
> one space to the other. In the
> pure space, the math-like functions can be highly optimized but only insofar
> as they do not disrupt the
> implied order of the IO actions.  Because of the type system, the program
> recognizes when it enters
> "back" into the IO space and follows different, less optimized rules.

You can effectively see it like that, but it must be noted that the
ordering of IO actions isn't special in any sense, it is just implied
by the strict data dependence encoded in the monad, the compiler don't
optimize differently the IO portion of the program.
"main" is the only function that is evaluated unconditionally, any
other value and/or function in a program is only evaluated if main
needs it.


More information about the Beginners mailing list