Proposal: Add getStdGenState and stdGenFromState

Bas van Dijk v.dijk.bas at gmail.com
Mon Feb 6 18:07:33 CET 2012


Dear Ryan, all,

To quote the documentation of System.Random: "The Show and Read
instances of StdGen provide a primitive way to save the state of a
random number generator."

Primitive it is indeed. Currently the only way to serialize (using
cereal or binary) a StdGen is to convert it to a String and then
serialize this String. This takes up many more bytes than are actually
needed.

I would like to propose a more efficient way of serializing the state
of the random number generator by providing the following two
functions:

getStdGenState :: StdGen -> (Int32, Int32)
getStdGenState (StdGen s1 s2) = (s1, s2)

stdGenFromState :: (Int32, Int32) -> StdGen
stdGenFromState (s1, s2) = StdGen s1 s2

Of course this satisfies:
(stdGenFromState . getStdGenState) g == g

Alternatively, instead of using (Int32, Int32) we can use an Int64:

getStdGenState :: StdGen -> Int64
getStdGenState (StdGen s1 s2) =
    fromIntegral s1 `unsafeShiftL` 32 .|.
    fromIntegral s2
#if !MIN_VERSION_base(4,5,0)
    where unsafeShiftL = shiftL
#endif

stdGenFromState :: Int64 -> StdGen
stdGenFromState s = StdGen
    (fromIntegral (s `unsafeShiftR` 32))
    (fromIntegral s)
#if !MIN_VERSION_base(4,5,0)
    where unsafeShiftR = shiftR
#endif

I don't really care which one we use but I think the latter is a bit
easier to use.

Oh, I don't really care about the names either.

Regards,

Bas



More information about the Libraries mailing list