[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