[Haskell-beginners] clarification on IO

Gregg Reynolds dev at mobileink.com
Sat Feb 28 05:30:52 EST 2009

On Fri, Feb 27, 2009 at 8:50 PM, 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?

Right, the IO primitives are not functions.

> 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.

It might be helpful to distinguish between internal side effects (e.g.
updating a global var in an imperative language) and external (IO).  Haskell
uses monads to simulate the former and to serialize the latter.

> 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?

Bear in mind that's the GHC implementation.  I'm told another implementation
uses some kind of continuation monad.  The only requirement as I understand
it is that the IO monad, however it is designed, must impose an order of
evaluation on the IO primitives.  GHC does hide the implementation details.

> 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.

Hmm, to me there's something fishy about thinking in terms of two spaces.
IO expressions are normal Haskell expressions; they just happen to get
sequenced because they get chained together by monad ops.  I.e. as far has
Haskell semantics is concerned they're not special; Haskell needn't know
they're impure.  The impure part is external the Haskell semantics.  Then
remember lazy evaluation; the whole program can be optimized at compile time
to some extent, and at run time evaluation is forced by the ordering of the
"IO chain" that leads to main.

Be careful about thinking of the program as "starting at main" and then
proceeding through the IO chain.  That's perilously close to imperative
thinking.  It's more accurate (IMO) to say that the program gets evaluated
at run time, which means main gets evaluated, and since the value of main
depends on the series of IO actions chained to it, they get forced in
order.  So main isn't really the "first thing that happens"; it's the ONLY
thing that happens, since the meaning of the program (i.e. main) is
equivalent to the evaluation of the IO chain.  Actual IO is a side effect of
evaluating main.

Hope it helps,

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20090228/a3c4a077/attachment-0001.htm

More information about the Beginners mailing list