Simon Peyton-Jones wrote:
> 
> | This is a limitation, which precludes the usage of some clever
> | generation algorithms needing e.g. a prime modulus, or introducing
> | a computational overhead, most probably useless.
> 
> The generator knows its own 'internal' range
> (e.g. your prime modulus).  All it needs to do is to generate
> random numbers uniformly distributed in the range [minBound,maxBound].
> (Actually, this has to be done with care; perhaps someone would
> like to send a reference solution to this problem; it's easier than
> the adaptive ones that have already been suggested.)
> 
> Mind you, to do this might take it several iterations, and these
> iterations are wasted if the ultimate customer is then mapping
> the [minBound,maxBound] range onto some smaller interval.
> So perhaps you are right that there's a significant performance
> cost to the minBound/maxBound story
> 
> Simon

Yes, and if your modulus is not 2^x, you will have to throw out up to
half the values.  Then you have to do that again when mapping to a range
that's not 2^x.  Darn.  Now I want the genRange operation again.  The
"clarification" can really be a significant performance cost.  Not to
mention, you're also shortening the period of the RNG (perhaps by a
factor of 4!).

Can we have both (see below)?

> class RandomGen g where
>    next :: g -> (Int, g)
>    split :: g -> (g, g)
>    genRange :: g -> (Int, Int)
>    genRange _ = (minBound, maxBound)

Put the "clarification" in, but then allow the implementer to optionally
provide a different range?  If a genRange is provided, it should fit the
requirements described earlier, of course.  And as someone suggested,
(genRange _|_) should always be defined (not _|_).

Regards,
Matt Harden

Reply via email to