
unsafeInterleaveIO allows embedding side effects into a pure computation. This means you can potentially observe if some pure value has been evaluated or not; the result of your code could change depending how lazy/strict it is, which is very hard to predict! For example:
-- given f :: Integer -> Integer
main = do r <- newIORef 0 v <- unsafeInterleaveIO $ do writeIORef r 1 return 1 x <- case f v of 0 -> return 0 n -> return (n - 1) y <- readIORef r print y
-- a couple of examples: f x = 0 -- program prints "0" -- f x = x -- program prints "1"
"f" is pure. But if f is nonstrict, this program prints 0, and if
it's strict, it prints 1. The strictness of a pure function can
change the observable behavior of your program!
Furthermore, due to the monad laws, if f is total, then reordering the
(x <- ...) and (y <- ...) parts of the program should have no effect.
But if you switch them, the program will *always* print 0.
Also, the compiller might notice that x is never used, and that "f" is
total. So it could just optimize out the evaluation of "f v"
completely, at which point the program always prints 0 again; changing
optimization settings modifies the result of the program.
This is why unsafeInterleaveIO is unsafe.
-- ryan
On Sun, Mar 15, 2009 at 11:31 AM, Yusaku Hashimoto
Hello,
I was studying about what unsafeInterleaveIO is.I understood unsafeInterleaveIO takes an IO action, and delays it. But I couldn't find any reason why unsafeInterleaveIO is unsafe.
I have already read an example in http://www.haskell.org/pipermail/haskell-cafe/2009-March/057101.html says lazy IO may break purity, but I think real matter in this example are wrong use of seq. did I misread? _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe