On Sun, Jul 25, 2010 at 11:39 AM, michael rice <span dir="ltr">&lt;<a href="mailto:nowgate@yahoo.com">nowgate@yahoo.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td style="font: inherit;" valign="top">Hi All,<br><br>From: <a href="http://en.wikibooks.org/wiki/Haskell/Understanding_monads/State" target="_blank">http://en.wikibooks.org/wiki/Haskell/Understanding_monads/State</a><br>
<br>                           Exercises<br><br>   1. Implement a function rollNDiceIO :: Int -&gt; IO [Int] that,<br>      given an integer, returns a list with that number of pseudo-<br>      random integers between 1 and 6.<br>
<br><br>After a lot of learning what not to do, this is the best I could come up with.<br><br>rollNDiceIO :: Int -&gt; IO [Int]<br>rollNDiceIO n = mapM (\x -&gt; randomRIO(1,6)) (replicate n 1)<br><br>I know, ugly, but at least I got it to work. What&#39;s a better way to generate this list?<br>
<br></td></tr></tbody></table></blockquote><div><br>An even better method lets the list be generated lazily.<br><br>import Data.Functor ((&lt;$&gt;))<br>import Random<br><br>rollDice :: IO [Int]<br>rollDice =  randomRs (1,6) &lt;$&gt; newStdGen<br>
<br>rollNDice :: Int -&gt; IO [Int]<br>rollNDice n = take n &lt;$&gt; rollDice<br><br>This is important because randomRIO has to peek at an MVar to determine the current value of the random number seed _for each die rolled_, but using randomRs on a fresh StdGen only has does so once.<br>
<br>Moreover, it gives you the more general &#39;rollDice&#39; funtion, which can give you an infinite list of random dice rolls. Trying to implement that function using the approach you used will lead to a computation that won&#39;t terminate.<br>
<br>-Edward Kmett<br></div></div>