
On Thu, Jul 08, 2004 at 11:44:38PM +0100, Alastair Reid wrote: [snip]
We can do better though. Using two functions in System.Random, it's easy to get an infinite list of random numbers:
randomRsIO :: IO [Int] randomRsIO = do g <- getStdGen return (randoms g) [snip]
Except that AFAICS, getStdGen gives you _the_ standard PRNG which means that you shouldn't use it (the standard PRNG) anymore afterwards, or you'll get repeated numbers: (getStdGen returns the current state without changing it) -- Return the current state and use it Prelude Random> getStdGen >>= print . take 10 . randomRs (0,9::Int) [4,5,9,0,9,5,6,3,5,3] -- Return & use it again and you'll get the _same answers_ Prelude Random> getStdGen >>= print . take 10 . randomRs (0,9::Int) [4,5,9,0,9,5,6,3,5,3] -- getStdRandom is a special use-and-consume function Prelude Random> (sequence $ replicate 10 $ getStdRandom $ randomR (0,9::Int)) >>= print [4,5,9,0,9,5,6,3,5,3] -- Finally: the last getStdRandom _did_ change the PRNG state Prelude Random> (sequence $ replicate 10 $ getStdRandom $ randomR (0,9::Int)) >>= print [1,5,0,7,8,6,6,4,4,1] newStdGen splits the current state (using one as the new stdGen and returning the other), which probably _is_ what you want. Except that I have no idea what hidden costs splitting random number generators have :) (anyone?) Prelude Random> newStdGen >>= print . take 10 . randomRs (0,9::Int) [4,9,9,2,3,2,9,6,9,3] Prelude Random> newStdGen >>= print . take 10 . randomRs (0,9::Int) [5,1,5,5,9,0,8,6,2,1] Prelude Random> (sequence $ replicate 10 $ getStdRandom $ randomR (0,9::Int)) >>= print [2,0,1,5,2,5,6,0,4,7] Prelude Random> (sequence $ replicate 10 $ getStdRandom $ randomR (0,9::Int)) >>= print [9,9,2,7,2,5,3,4,0,0] Prelude Random> Groeten, Remi -- Nobody can be exactly like me. Even I have trouble doing it.