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 If I remember correctly, one of the Griswold systems on the path between SNOBOL and Icon had a special feature for looking below the language level, called "The Window into Hell". Derek Lowe has a list of "Things I Won't Work With". http://pipeline.corante.com/archives/things_i_wont_work_with/ unsafeInterleaveST has just joined my "Things I Won't Work With" list. But since it is new to me, I don't understand what it does or *how* it breaks this code. Does it involve side effects being reordered in some weird way? I think there is a big difference between this and lazy I/O. unsafeInterleaveST *sounds* dangerous. Lazy I/O *sounds* safe. And most of the alternatives (like conduits) hurt my head, so it is really *really* tempting to stay with lazy I/O and think I'm doing something safe. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe