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

Scott Turner p.turner at computer.org
Mon Apr 25 05:46:56 EDT 2005

On 2005 April 25 Monday 02:16, Michael Vanier wrote:
> -- Generate an infinite list of coin flips.
> coinFlips :: IO [Coin]
> coinFlips = sequence cfs
>             where cfs = (coinFlip : cfs)
> ----------------------------------------------------------------------
> [...] 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,
Names that have type IO t (such as coinFlip and coinFlips) are actions that, 
when invoked, are guaranteed to be executed in sequence.  CoinFlips cannot 
terminate because it invokes the coinFlip action an infinite number of times.

> and how do I fix it? 
In this case, you can add a parameter to coinFlips.
> -- Generate an finite list of coin flips.
> coinFlips :: Integer -> IO [Coin]
> coinFlips n = sequence cfs
>             where cfs = take n (coinFlip : cfs)

What you have in mind is more along the lines of using the Random module's 
'randoms', as in
    test n <- do
        rng <- getStdGen
        print (take n (randoms rng :: [Bool]))
In the above, 'randoms rng' is an infinite list of random Bool values.  You 
want an infinite list of Coin values.  You can transform the list of Bool to 
list of Coin.

Even niftier is to make Coin an instance of the Random class, to enable the 
    test n <- do
        rng <- getStdGen
        print (take n (randoms rng :: [Coin]))

More information about the Haskell-Cafe mailing list