
'split' has type split :: StdGen -> (StdGen, StdGen) It takes a generator and produces two independent generators. The old version of variant calls 'split' n times to get a new generator, and it only calls "split" on the second result. The new version calls split (log n) times. It gets a unique generator for each value of n by using both results from split. For example, rands 2 r0 = let (r1, r2) = split r0 (r3, r4) = split r1 in r4 rands 3 r0 = let (r1,r2) = split r0 (r3',r4') = split r2 in r4' Patrick On Aug 14, 2008, at 4:57 AM, Johan Tibell wrote:
On Thu, Aug 14, 2008 at 12:15 PM, Patrick Perry
wrote: 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'
It's not really clear to me how this works. Could you please explain?
Cheers,
Johan