Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- What about applications of unsafeInterleaveIO to IO computations that don't actually do any input/output, but uses other features of the IO monad? I'm thinking in particular of random number generation. For example, here's how to talk a random step, left or right:
- > step :: Int -> IO Int
- > step n = do { b <- randomIO ; return (if b then (n+1) else (n-1)) }
- The obvious program to take a random walk is unproductive:
- > walk :: Int -> IO [Int]
- > walk n = do { n' <- step n ; ns <- walk n' ; return (n : ns) }
- But with an unsafeInterleaveIO, it becomes productive:
- > walk' :: Int -> IO [Int]
- > walk' n = do { n' <- step n ; ns <- unsafeInterleaveIO (walk' n') ; return (n : ns) }
- Is this impure, or unsafe, or otherwise A Bad Thing? I'd say random number generation is (at least morally) impervious to concurrency. I know that *pseudo* random number generation is not so impervious; different numbers will be generated, depending on evaluation order, but you shouldn't care about that, should you? For example,
- *Main> let m = unsafeInterleaveIO (randomIO :: IO Int)
- *Main> let reset = setStdGen (mkStdGen 17)
- *Main> do { reset ; x <- m ; y <- m ; return y }
- 7352521803991849760
- *Main> do { reset ; x <- m ; y <- m ; return y }
- 7352521803991849760
- *Main> do { reset ; x <- m ; y <- m ; x `seq` return y }
- -4752852439639411777
Advertisement
Add Comment
Please, Sign In to add comment