Monday, May 12, 2014

The IO monad has a non-strict bind

The Maybe monad has a bind function that is strict in its arguments:

The IO monad however has a non-strict bind function:

And so does the strict State monad:

It's easy to see in the source code:

To reduce m >>= k to Weak Head Normal Form, you only need to go as far as the StateT constructor; you don't need to touch any of the parameters. I suppose something similar happens with IO.

What's so strict then about the IO monad and the strict State monad? Their run functions. This:

As opposed to this:

Notice how in the strict case putting the expression in WHNF with seq is enough to trigger the exception.

Of course, with IO we don't have a explicit run function (one that isn't evil, I mean). We just put the IO action into main.

Notice however that even the strict State monad is not too strict:

This doesn't trigger an exception, either:

But this does:

Some good links about laziness here, here, here, here, here and here.