How does lazy evaluation interplay with MVars?
Yes, it's real. You get around it by avoiding all the base
functions that are implemented using unsafeInterleaveIO
. I don't have a complete list, but that's at least readFile
, getContents
, hGetContents
. IO actions that don't do lazy IO -- like hGet
or hGetLine
-- are fine.
If you must use lazy IO, then fully evaluate its results in an IO action inside the critical section, e.g. by combining rnf
and evaluate
.
Some other commentary on related things, but that aren't directly answers to this question:
Laziness and lazy IO are really separate concepts. They happen to share a name because humans are lazy at naming. Most IO actions do not involve lazy IO and do not run into this problem.
There is a related problem about stuffing unevaluated pure computations into your
MVar
and accidentally evaluating it on a different thread than you were expecting, but if you avoid lazy IO then evaluating on the wrong thread is merely a performance bug rather than an actual semantics bug.