# [Haskell-cafe] Why doesn't this work?

Sebastian Sylvan sebastian.sylvan at gmail.com
Mon Apr 25 05:40:41 EDT 2005

```On 4/25/05, Michael Vanier <mvanier at cs.caltech.edu> wrote:
>
> I've been trying to generate an infinite list of random coin flips in GHC
> 6.4, and I've come across some strange behavior:
>
> ----------------------------------------------------------------------
> import System.Random
>
> data Coin = H | T deriving (Eq, Show)
>
> -- Generate a random coin flip.
> coinFlip :: IO Coin
> coinFlip = do b <- getStdRandom random
>               return (bool2coin b)
>            where
>               bool2coin True  = H
>               bool2coin False = T
>
> -- Generate an infinite list of coin flips.
> coinFlips :: IO [Coin]
> coinFlips = sequence cfs
>             where cfs = (coinFlip : cfs)
>
> -- Print n of them.
> test :: Int -> IO ()
> test n = do f <- coinFlips
>             print (take n f)
> ----------------------------------------------------------------------
>
> Now when I do "test 1" (for instance), it hangs forever.  It seems as if
> there is some kind of strictness constraint going on that I don't
> understand.  My understanding is that cfs is an infinite list of (IO Coin),
> sequence lifts this to be IO [Coin] where [Coin] is an infinite list, and
> then test should extract the infinite list of coin flips into f, take some
> number of them, and print them.  But instead, the system appears to be
> trying to compute all the coin flips before taking any of them.  Why is
> this, and how do I fix it?
>

I think you're doing too much in the IO monad and sequence introduces
unwanted strictness.

coins :: RandomGen g => g -> [Coin]
coins g = map bool2coin (randoms g)
where bool2coin True = H
bool2coin False = T

coinFlips :: IO [Coin]
coinFlips = do g <- newStdGen
return (coins g)

test :: Int -> IO ()
test n = do f <- coinFlips
print (take n f)

Basically: Don't do stuff in the IO monad unless it really belongs in