[Haskell-cafe] In relation to shuffling

Remi Turk rturk at science.uva.nl
Fri Jul 9 06:54:22 EDT 2004


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.


More information about the Haskell-Cafe mailing list