[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
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.
More information about the Haskell-Cafe
mailing list