On Thu, Apr 11, 2013 at 12:49:40PM +1200, Richard A. O'Keefe wrote: > On 10/04/2013, at 2:45 PM, <o...@okmij.org> 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 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe