[Haskell] Laziness and the IO Monad (randomness)

Dave Tapley dukedave at gmail.com
Thu Mar 1 12:45:16 EST 2007


Hi all, I am having a problem with the implementation of a program (a
genetic algorithm) which requires randomness in it.

It all hinges on the ability to generate something (in the example below an
Int), then provide a function to update it such that the prelude's
iteratefunction (or an equivalent) may be used. In my program I
require that both
the generation and the updating function contain randomness.

I have drafted a (simplified) example of my problem:

This code show a trivial case where randomness (and hence the IO monad) is
not used and the first 10 elements of the produced list are printed:

aNum :: Int
aNum = 2

addTwo :: Int -> Int
addTwo = (+) 2

firstTen :: [Int]
firstTen = take 10 (iterate addTwo aNum)

main :: IO ()
main = do
    print firstTen

As required the program terminates printing:
[2,4,6,8,10,12,14,16,18,20]

Now I present my 'conversion' of this trivial case where we both generate a
random number, and add a random amount to it upon each iteration. Again we
only wish to print the first 10:

import System.Random

-- Taken directly from function 'rollDice' in Haskell98 report
randNum :: IO Int
randNum = getStdRandom (randomR (1, 6))

addRand :: Int -> IO Int
addRand x = do
    y <- randNum
    return (x + y)

firstTen :: IO [Int]
firstTen = do
    infiniteNums <- iterateM addRand randNum
    return (take 10 infiniteNums)

main :: IO ()
main = do
    tenNums <- firstTen
    print tenNums


-- Monadic interpretation of prelude iterate definition
iterateM :: Monad m => (a -> m a) -> m a -> m [a]
iterateM f xM = do
    x <- xM
    mcons xM (iterateM f (f x))

-- Taken from prelude definition of sequence
mcons :: Monad m => m a -> m [a] -> m [a]
mcons p q = p >>= \x -> q >>= \y -> return (x:y)


However this latter case gets stuck in an infinite loop, terminating on a
stack overflow.

My question asks why this is the case, when laziness should ensure only the
first 10 cases need to be computed.

If anyone wishes to suggest another way entirely to approach this problem
that would also be welcome!

Many Thanks,
Dave
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell/attachments/20070301/f6273a81/attachment-0001.htm


More information about the Haskell mailing list