IO behaves oddly if used nested
l4t3r at hotmail.com
Sat Oct 4 14:13:59 EDT 2003
> Neither example is odd behavior, unless
>you consider Hugs providing a perfectly reasonable instance of Show for
>IO a odd.
True, every program behaves exactly as according to the definition of the
run-time behavior of Haskell programs. (Hugs deviates a bit from ghc but ah
well) The odd is not in the run-time behavior.
The odd is in the conceptual explanation. If I give a description of some f
x = y function in Haskell I expect that some program f x is reduced to y and
the result is given back (possibly printed). A good story to sell to
This is almost everywhere the case except for the IO monad. In the former
example, the inner putStr is _not_ evaluated but a message is shown (hinting
that a IO has some structure we can observe before evaluation). In the
latter example, it is shown that we are not interested in a result of a IO
program, but only in its (lazily generated) side-effects. The monad behaves
oddly with respect to the f x = y behavior.
I think I observe the following reactions when I explain IO:
1* Can't the guy in front of me stop poking his nose? (the blank faces and
2* Hmm, feels like Java, looks like Java, ahah! is Java! (coders)
3* Hmm, feels like math, looks like math, ahah! is math! (designers and
Group 1 will mimic, group 2 will produce obfuscuated Java code in Haskell,
group 3 has great difficulty with the IO monad (although they are the first
group who will write OK haskell programs) because it behaves differently
from what they expect. The usual questions of group 3:
* Why is an IO a evaluated if I am not interested in it's result? (opposite
to the f x = y lazy behavior)
* Why is in the putStr "hello world" example Hello World not shown?
(opposite to expected f x = y eval-first-then-show behavior)
* Why is in the IO (IO ()) example the inner IO () not evaluated? (somewhat
opposite to expected f (f x) behavior - I personally wonder if it is even
sound in a category theoretical setting)
* ...Lots of other questions...
Hmm, have to finish this email now - time constraints. I guess the short
story just is: IO monads == sometimes bad conceptual story to sell.
Especially so since the "best" group has the biggest problems and
non-trivial examples are only explainable in the end in terms of run-time
behavior. What was that remark again about pointy headed people and Haskell?
For that I also gave the Nomad datatype as a possible solution (needs a
pretty hefty type checker though). A nice (old) idea would be to represent
IO as programs which are interpreted by some _outside_ RTS in a given
manner, and leave the Haskell language clean.
(It might even be a good idea with respect to the compiler implementation
since it removes checking against unsafe IO behavior from the compiler --
just a thought)
Bye now, and cheers,
The new MSN 8: smart spam protection and 2 months FREE*
More information about the Haskell