IO a is an abstract type is an abstract type is ..
Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:
IMHO "IO a" *is* roughly equivalent to "World -> (World, a)",
claiming that we couldn't tell the difference, e.g., because we couldn't
get hold of values of type World. Well, one of the early implementations
of Haskell's monadic IO seemed to work on a similar assumption and used
to accept something much like the following without producing the
expected(?) behavior:
-- one world is not enough
main = \world-> cakeAndEatIt world world
-- now that we have some worlds, let's use them
cakeAndEatIt w1 w2 =
let
(usedWorld,riches) = consumeAllResources w1
(goodWorld,()) = addToWorld riches w2
in (goodWorld,())
-- where consumeAllResources and addToWorld are the usual
-- non-standard IO primitives
Clean uses World-passing style, but *guarded by a static uniqueness
check* (built into/expressed as a static type system)! Haskell uses
IO-script construction style. *Some implementations* may translate
IO-script construction style into World-passing style *in such a way
that the resulting programs avoid uniqueness problems by construction*,
but that is not directly relevant at the *language level*.
As has been pointed out, such a translation is only one of many possible
implementations of monadic i/o, and unless you keep the side-conditions
in mind, thinking in terms of such a translation will not help you to
understand monadic i/o.
Here goes another attempt:-) If you think of a language as a means to
talk about the things you are interested in, then Clean and Haskell
take slightly different approaches to i/o, with slightly different
tradeoffs:
In Clean, you can talk about the world itself. As the world itself
happens to be a very special thing, programs that want to use the
world have to adhere to certain unusual restrictions. The resulting
style is easily extended to (parts of) a single program working on
multiple (independent parts of the) world(s) (deterministic
concurrency in the sense of Clean's multiple environment passing).
In Haskell, you can talk about interactions with the world. As
interactions are not like functions, they are executed only at the
borderline between functional programs and their runtime environments,
not at arbitrary points inside the functional programs (where they are
just values of some abstract type). The resulting style is easily
extended to multiple programs interacting with an external world and
with each other (non-deterministic concurrency in the sense of
Concurrent Haskell).
Hth,
Claus