Simon Marlow writes:
| All known Haskell compilers implement the IO type as a function type,
| something like (World -> (World, a)). You can think of the monad
| as just a convenient way to hide the passing around of the world token.
|
| And because it is abstract, compilers are free to implement it
| however they like.
I would refute Simon's first point (it depends on how you interpret
the word "compiler"), but strongly support his second. In Hugs, I
did actually use a different implementation of the IO monad, based
on continuation passing, which looked something like:
IO a = (a -> Ans) -> (IOError -> Ans) -> Ans
In other words, there is no explicit World, and a choice of two
continuations, one for success, and one for failure. I haven't
looked to see if things have changed since the new team took over
Hugs; presumably they will because Hugs and GHC will have to agree
on what an IO a is if they're going to interoperate. Nevertheless,
my point remains: you shouldn't think of an (IO a) value as a world
passing function, but as an abstract datatype that represents a
certain kind of computation, and which may admit more than one
implementation.
All the best,
Mark