
On 10/04/2013, at 2:45 PM,
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.