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



Reply via email to