Guest User

unsafeInterleaveIO and random numbers

a guest
Sep 27th, 2015
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.32 KB | None | 0 0
  1. 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:
  2.  
  3. > step :: Int -> IO Int
  4. > step n = do { b <- randomIO ; return (if b then (n+1) else (n-1)) }
  5.  
  6. The obvious program to take a random walk is unproductive:
  7.  
  8. > walk :: Int -> IO [Int]
  9. > walk n = do { n' <- step n ; ns <- walk n' ; return (n : ns) }
  10.  
  11. But with an unsafeInterleaveIO, it becomes productive:
  12.  
  13. > walk' :: Int -> IO [Int]
  14. > walk' n = do { n' <- step n ; ns <- unsafeInterleaveIO (walk' n') ; return (n : ns) }
  15.  
  16. 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,
  17.  
  18. *Main> let m = unsafeInterleaveIO (randomIO :: IO Int)
  19. *Main> let reset = setStdGen (mkStdGen 17)
  20. *Main> do { reset ; x <- m ; y <- m ; return y }
  21. 7352521803991849760
  22. *Main> do { reset ; x <- m ; y <- m ; return y }
  23. 7352521803991849760
  24. *Main> do { reset ; x <- m ; y <- m ; x `seq` return y }
  25. -4752852439639411777
Advertisement
Add Comment
Please, Sign In to add comment