
Actually, a much better solution is: variant :: Int -> Gen a -> Gen a variant v (Gen m) = Gen (\n r -> m n (rands r v)) where rands r0 0 = r0 rands r0 n = let (r1,r2) = split r0 (n',s) = n `quotRem` 2 in case s of 0 -> rands r1 n' _ -> rands r2 n' Patrick On Aug 14, 2008, at 2:17 AM, Johan Tibell wrote:
On Thu, Aug 14, 2008 at 1:58 AM, Patrick Perry
wrote: variant :: Int -> Gen a -> Gen a variant v (Gen m) = Gen (\n r -> m n (rands r !! v')) where v' = abs (v+1) `mod` 10000 rands r0 = r1 : rands r2 where (r1, r2) = split r0
Note that if you have a uniformly distributed random value in [0, n) and take its value mod k you don't end up with another random uniformly distributed value unless n `mod` k == 0. Consider n = 3 and k = 2. What you can do is to throw away all random numbers larger than n - (n `mod` k) and just generate a new number. This will terminate with a high probability if n >> k.
Cheers,
Johan