[Haskell-cafe] Monads, do and strictness

Steve Horne sh006d3592 at blueyonder.co.uk
Sat Jan 21 19:08:02 CET 2012

On 21/01/2012 17:29, Victor S. Miller wrote:
> The "do" notation translates
> do {x<- a;f}  into
> a>>=(\x ->  f)
> However when we're working in the IO monad the semantics we want requires that the lambda expression be strict in its argument.  So is this a special case for IO?  If I wanted this behavior in other monads is there a way to specify that?
IO is a special case, but strictness isn't the issue.

The value x cannot be evaluated in concrete form (I think the technical 
term is "head normal form") until the IO action a has been executed. 
However, evaluating to head normal form isn't really the key issue. The 
key issue is that the effects of the action must occur at the correct time.

This is why the internals of the IO monad are a "black box" (you can't 
use pattern matching to sneak a look inside a cheat the evaluation 
order) and, yes, it's why the IO monad is a bit special.

But you could still in principle use a non-strict evaluation order. It's 
a bit like evaluating (a + b) * c - you don't need to specify strict, 
lazy or whatever to know that you need to evaluate (a + b) before you 
can evaluate the (? + c), that aspect of evaluation ordering is fixed 

In this case, it's just that instead of being able to rewrite the (\x -> 
f) to (\someExpression -> f), there is no expression that you can insert 
there - there is e.g. no unary operator to extract out the result of an 
action and make it available as a normal value outside the IO context. 
If there were, it could defeat the whole point of the IO monad.

Even so, to see that strictness isn't the issue, imagine that (>>=) were 
rewritten using a unary executeActionAndExtractResult function. You 
could easily rewrite your lamba to contain this expression in place of 
x, without actually evaluating that executeActionAndExtractResult. You'd 
still be doing a form of composition of IO actions. And when you finally 
did force the evaluation of the complete composed expression, the 
ordering of side effects would still be preserved - provided you only 
used that function as an intermediate step in implementing (>>=) at least.

BTW - there's a fair chance I'm still not understanding this correctly 
myself (still newbie), so wait around to see everyone explain why I'm 
insane before taking this too seriously.

More information about the Haskell-Cafe mailing list