[Haskell-cafe] Mersenne-random and standard random API

Jerzy Karczmarczuk jerzy.karczmarczuk at unicaen.fr
Thu Feb 9 14:28:18 CET 2012

Aleksey Khudyakov:
> On 09.02.2012 15:32, Jerzy Karczmarczuk wrote:
>> 1. Mersenne Twister, AND congruential generators AND the Marsaglia
>> stuff, all use some kind of "seed", all are stateful. There are no
>> miracles. Just look the agressive monadization, the form of defaultSeed,
>> etc. within MWC.hs, before saying that this generator doesn't rely on
>> some global state.
> I think you are missing the point here. Surely all PRNG carry some 
> state around. But both StdGen and mwc-random (and likely many others)
> allow to have many generators at once (for use in different threads)
This is irrelevant. I believe that there is a misunderstanding in 
terminology. When I say "global state" it means not a local variable in 
some function. You seem to say "one object per programme". This is 
confirmed by:

> mersenne-random is just wrapper around vastly impure library (as
> documentation says) and allows only one genrator per program.
> This is why I said it uses *global* state

>> In any case, the seed changes after each generation, and
>> must be stored somewhere.
> No. It doesn't and cannot
> > data StdGen
> >  = StdGen Int32 Int32
> If generator state is stored in IORef it's not possible to implement
> `next :: g → (Int,g)'. To do something useful with it one have to
> go to IO monad but we can't. So state have to be copied.
We can't WHAT?
Look, all data that change or are created MUST be stored somewhere, 
don't say dubious things. Your next function is a "threading generator", 
which makes another StdGen, OK, but this is not a "copy". This is a 
creation of a new seed. When I spoke about IORefs, I thought about the 
global generator, which USES the l'Ecuyer stuff, newStdGen and its friends.

The threading becomes implicit. Try, say
r >>= return . next

and you will see, it works, and you don't keep explicitly your seed. 
 From the efficiency point of view all this is comparable. With IOrefs 
you do not "pollute" the memory which has to be garbage-collected, but 
its administration is heavier than the standard heap operations. StdGen 
with l'Ecuyer two-number seed, or some 600 of the Mersenne, I don't see 
a conceptual difference. The Marsaglia generator has a global seed quite 
voluminous as well.

>   ...sometimes it's not possible to implement some algorithms
> for particular API. For example if PRNG rely on in-place array updates
> it cannot implement Random type class.

No idea what do you mean. In the Random library you will find the 
generators using IORefs, AND the class Random, with the member random 
(or randomR, etc.) and you may  write
getStdRandom random
getStdRandom random
as you wish, getting different results. What's wrong with that?

Jerzy Karczmarczuk

More information about the Haskell-Cafe mailing list