
On Thu, Apr 11, 2013 at 12:49:40PM +1200, Richard A. O'Keefe wrote:
On 10/04/2013, at 2:45 PM,
wrote: ... unsafeInterleaveST is really unsafe ... import Control.Monad.ST.Lazy (runST) import Control.Monad.ST.Lazy.Unsafe (unsafeInterleaveST) import Data.STRef.Lazy
bad_ctx :: ((Bool,Bool) -> Bool) -> Bool bad_ctx body = body $ runST (do r <- newSTRef False x <- unsafeInterleaveST (writeSTRef r True >> return True) y <- readSTRef r return (x,y))
t1 = bad_ctx $ \(x,y) -> x == y -- True t2 = bad_ctx $ \(x,y) -> y == x -- False
[...]
I don't understand what it does or *how* it breaks this code. Does it involve side effects being reordered in some weird way?
As I understand it, unsafeInterleaveST defers the computation of x, so * if x is forced before y, then "writeSTRef r True" is run before "readSTRef r", thus the latter yields "True" * if y is forced before x, then "writeSTRef r True" is run after "readSTRef r", thus the latter yields "False" Tom