Hi all, I am having a problem with the implementation of a program (a genetic algorithm) which requires randomness in it.<br><br>It all hinges on the ability to generate something (in the example below an <span style="font-family: courier new,monospace;">


Int</span>), then provide a function to update it such that the prelude&#39;s 
<span style="font-family: courier new,monospace;">iterate</span>
function (or an equivalent) may be used. In my program I require that
both the generation and the updating function contain randomness.<br><br>I have drafted a (simplified) example of my problem:
<br><br>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:
<br><br><span style="font-family: courier new,monospace;">aNum :: Int</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">aNum = 2</span><br style="font-family: courier new,monospace;">




<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">addTwo :: Int -&gt; Int</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">




addTwo = (+) 2</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">firstTen :: [Int]</span><br style="font-family: courier new,monospace;">




<span style="font-family: courier new,monospace;">firstTen = take 10 (iterate addTwo aNum)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">




main :: IO ()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">main = do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">




&nbsp;&nbsp;&nbsp; print firstTen</span><br style="font-family: courier new,monospace;"><br>As required the program terminates printing:<br><span style="font-family: courier new,monospace;">[2,4,6,8,10,12,14,16,18,20]</span><br><br>Now
I present my &#39;conversion&#39; 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:
<br><br><span style="font-family: courier new,monospace;">import System.Random</span><br style="font-family: courier new,monospace;"><br><span style="font-family: courier new,monospace;">-- Taken directly from function &#39;rollDice&#39; in Haskell98 report
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">randNum :: IO Int</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">




randNum = getStdRandom (randomR (1, 6))</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">addRand :: Int -&gt; IO Int</span>




<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">addRand x = do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; y &lt;- randNum
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; return (x + y)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">




<span style="font-family: courier new,monospace;">firstTen :: IO [Int]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">firstTen = do</span><br style="font-family: courier new,monospace;">




<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; infiniteNums &lt;- iterateM addRand randNum</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; return (take 10 infiniteNums)
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">main :: IO ()</span><br style="font-family: courier new,monospace;">




<span style="font-family: courier new,monospace;">main = do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; tenNums &lt;- firstTen</span><br style="font-family: courier new,monospace;">




<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; print tenNums</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">




-- Monadic interpretation of prelude iterate definition</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">iterateM :: Monad m =&gt; (a -&gt; m a) -&gt; m a -&gt; m [a]
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">iterateM f xM = do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">




&nbsp;&nbsp;&nbsp; x &lt;- xM</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; mcons xM (iterateM f (f x))</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">




<span style="font-family: courier new,monospace;">-- Taken from prelude definition of sequence</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">mcons :: Monad m =&gt; m a -&gt; m [a] -&gt; m [a]
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">mcons p q = p &gt;&gt;= \x -&gt; q &gt;&gt;= \y -&gt; return (x:y)<br><br><br></span>However this latter case gets stuck in an infinite loop, terminating on a stack overflow.
<br><br>My question asks why this is the case, when laziness should ensure only the first 10 cases need to be computed.<br><br>If anyone wishes to suggest another way entirely to approach this problem that would also be welcome!
<br><br>Many Thanks, <br><span><span>Dave</span></span>