Matt Harden wrote:
> I don't think that's really true.  If I understand it correctly, the
> state can be any type; it doesn't have to fit in, say, an Int or other
> small type.  I think the Mersenne Twister could be implemented as an
> instance of Random.RandomGen.  The only thing is I don't really know the
> best way to implement "split" for MT.
Well yes you can implement MT using the Haskell Random's
existing framework, but since the "next" function,
which steps the generator, has type
  next :: g -> (Int,g)
the compiler must either
  (1) update the entire state persistently, which probably
      means some horrid hack with trees, if you don't want
      to have to copy arrays around
or
  (2) do static analysis to detect that (as in most cases)
      the generator is not being replicated, so you don't
      need persistence.  I think the "Haskell Way", which
      is better, is instead to enforce single-threading via
      some kind of monad.
Actually I would argue that this is a rare case where persistence is
not only not wanted but dangerous.  If you have old copies of the state
hanging around they may get accidentally used so that you have the same
non-random numbers occurring again.  You do _sometimes_ want to set and
unset the seed, perhaps once per program, but it is surely better to 
have explicit copying only in this case.
[snip[
> Yes, and the current interface provides randomIO and randomRIO for those
> who don't want to have to pass the RandomGen instance around.  The cost
> is they have to use the IO monad.
True, but a conformant implementation has to implement randomIO and randomRIO
using the same type of state (see section 17.3 of the library standard) and
so they will suffer from the same disadvantages.  Also the interface I suggest
is superior because it allows more than one random number generator.  (You
might for example have an independent part of the program which relies on
having its own personal deterministic reseedable generator.)

Reply via email to