
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 anyway. 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.