On Sun, Jul 25, 2010 at 11:39 AM, michael rice <nowgate@yahoo.com> wrote:
Hi All,
From: http://en.wikibooks.org/wiki/Haskell/Understanding_monads/State
Exercises
1. Implement a function rollNDiceIO :: Int -> IO [Int] that, given an integer, returns a list with that number of pseudo- random integers between 1 and 6.
After a lot of learning what not to do, this is the best I could come up with.
rollNDiceIO :: Int -> IO [Int] rollNDiceIO n = mapM (\x -> randomRIO(1,6)) (replicate n 1)
I know, ugly, but at least I got it to work. What's a better way to generate this list?
|
An even better method lets the list be generated lazily.
import Data.Functor ((<$>))
import Random
rollDice :: IO [Int]
rollDice = randomRs (1,6) <$> newStdGen
rollNDice :: Int -> IO [Int]
rollNDice n = take n <$> rollDice
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.
Moreover, it gives you the more general 'rollDice' 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't terminate.
-Edward Kmett