Is the monadic IO construct in Haskell just a convention?

Viewed 3748

Regarding Haskell's monadic IO construct:

  • Is it just a convention or is there is a implementation reason for it?

  • Could you not just FFI into libc.so instead to do your I/O, and skip the whole IO-monad thing?

  • Would it work anyway, or is the outcome nondeterministic because of:

    (a) Haskell's lazy evaluation?

    (b) another reason, like that the GHC is pattern-matching for the IO monad and then handling it in a special way (or something else)?

What is the real reason - in the end you end up using a side effect, so why not do it the simple way?

5 Answers

What is the real reason - in the end you end up using a side effect, so why not do it the simple way?

...you mean like Standard ML? Well, there's a price to pay - instead of being able to write:

any :: (a -> Bool) -> [a] -> Bool
any p = or . map p

you would have to type out this:

any :: (a -> Bool) -> [a] -> Bool
any p []     = False
any p (y:ys) = y || any p ys

Could you not just FFI into libc.so instead to do your I/O, and skip the whole IO-monad thing?

Let's rephrase the question:

Could you not just do I/O like Standard ML, and skip the whole IO-monad thing?

...because that's effectively what you would be trying to do. Why "trying"?

  • SML is strict, and relies on sytactic ordering to specify the order of evaluation everywhere;

  • Haskell is non-strict, and relies on data dependencies to specify the order of evaluation for certain expressions e.g. I/O actions.

So:

Would it work anyway, or is the outcome nondeterministic because of:

(a) Haskell's lazy evaluation?

(a) - the combination of non-strict semantics and visible effects is generally useless. For an amusing exhibition of just how useless this combination can be, watch this presentation by Erik Meiyer (the slides can be found here).

Related