[Haskell-cafe] Lazy MWC Random?

Aleksey Khudyakov alexey.skladnoy at gmail.com
Wed Jan 29 15:48:41 UTC 2014

On 01/28/2014 10:08 PM, Sacha Sokoloski wrote:
> Dear Haskellers,
> I'm in a situation where I'd like to generate an infinite list of random
> elements (basically, I'm simulating stochastic systems). I feel like MWC
> Random is the fastest RNG available, but when I try to pull the infinite
> list out of RandST, it obviously doesn't halt, because ST is strict.
> Someone posted a way around this in this stack overflow thread:
> https://stackoverflow.com/questions/16248600/parallel-computations-with-fast-randomness-and-purity
> Which would fix my problem. My question is though, why isn't ST.Lazy
> included as a PrimMonad instance anyway? The best answer I can come up
> with is that, since evaluating the Generator is time dependent, it's
> best to make it strict to make sure that one's program isn't tapping
> into /dev/random at arbitrary times.
> In this way the best stackoverflow solution is quite good. It requires
> one to strictly generate a Seed (since that's the only way to do it),
> but then converts the ST Monad to the Lazy version to Lazify everything
> else. However, my understanding of PrimMonad is simply that it's a class
> of low level monads i.e. IO and ST, so if there's some deeper reason to
> this, it's beyond me.

Definition of PrimMonad is basically monad which is isomorphic to strict 
ST/IO. It's possible to define instance for lazy ST but I'm not sure how 
well will it interact with lazyness.

> Another question that I'm puzzling over: In the stack overflow solution,
> they also make an effort to only have to generate the seed a single
> time. Is this important performance wise? What I suppose this must hinge
> upon, is whether in saving an ST s Gen to a Seed, the conversion from an
> immutable to mutable array requires a copy or not. Is that the full
> extent of the complexity of this? Is the stackoverflow solution
> ultimately the most efficient? Is using MWC Random to generate infinite
> lists and efficient solution anyway?
Conversions between Gen and Seed require copying a generator state. 
Internally Gen is 258 element array of Word32. So to get good 
performance one want to create Gen once and then modify it in place.
To understand whether SO solution is efficient you ned to benchmark it.

More information about the Haskell-Cafe mailing list