On Thu, Apr 11, 2013 at 12:49:40PM +1200, Richard A. O'Keefe wrote:
> On 10/04/2013, at 2:45 PM, <[email protected]> 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
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe