# Understanding unsafeInterleaveIO

July 14, 2015

While answering some question in StackOverflow, I came across this following piece of code which won’t terminate:

``````import System.Random

g :: IO [Integer]
g = do
n <- randomRIO (1,6) :: IO Integer
f <- g
return (n : f)``````

So, now we can see why this piece of computation doesn’t terminate. The line `f <- g` specifically makes it go on and on. Now can we make it work using `unsafeInterleaveIO`:

``````import System.Random
import System.IO.Unsafe (unsafeInterleaveIO)

g :: IO [Integer]
g = do
n <- randomRIO (1,6) :: IO Integer
f <- unsafeInterleaveIO g
return (n : f)``````

In a sample GHCI session:

``````λ> g >>= \x -> return \$ take 5 \$ x
[1,2,2,5,6]``````

With a Bang!, we can again make it non-terminating:

``````{-#LANGUAGE BangPatterns#-}

import System.Random
import System.IO.Unsafe (unsafeInterleaveIO)

g :: IO [Integer]
g = do
n <- randomRIO (1,6) :: IO Integer
!f <- unsafeInterleaveIO g
return (n : f)``````

And in GHCI:

``````λ> g >>= \x -> return \$ take 5 \$ x
C-c C-c Interrupted.``````

Note that I still believe it’s a bad option to use `unsafeInterleaveIO` unless there is no other go. But I find this example as a nice way to understand the working of `unsafeInterleaveIO`.