This is a follow-up to my previous question
Suppose I have a RandomGen[A]
monad.
This is actually a function: Long => (Long, A)
with map
and flatMap
and another function certain
to create a new instance of RandomGen
(as return in Haskell)
class RandomGen[A](run: Long => (Long, A)) {
def apply(seed: Long) = run(seed)
def flatMap[B](f: A => RandomGen[B]): RandomGen[B] =
new RandomGen(seed => {val (seed1, a) = run(seed); f(a)(seed1)})
def map[B](f: A => B): RandomGen[B] =
new RandomGen(seed => {val (seed1, a) = run(seed); (seed1, f(a))})
}
def certain[A](a: A): RandomGen[A] = new RandomGen(seed => (seed, a))
Suppose also I have a generator of random bits
def nextbits(bits: Int): RandomGen[Int] = ...
Now I would like to add new generator that yields random numbers between 0 and a given n
. I copied the implementation from java.util.Random and omitted the special case where n
is a power of two for simplicity.
def integer(n: Int): RandomGen[Int] =
nextbits(31).flatMap {r =>
val value = r % n
if (r - value + (n -1) < 0) integer(n) else certain(value)
}
Does it make sense ?