[Haskell-cafe] unsafeInterleaveST (and IO) is really unsafe [was: meaning of "referential transparency"]
Tom Ellis
tom-lists-haskell-cafe-2013 at jaguarpaw.co.uk
Thu Apr 11 10:05:34 CEST 2013
On Thu, Apr 11, 2013 at 12:49:40PM +1200, Richard A. O'Keefe wrote:
> On 10/04/2013, at 2:45 PM, <oleg at 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
More information about the Haskell-Cafe
mailing list