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