1 module Main where
4 import System.Random.TF.Gen
5 import System.Random.TF.Instances
7 splitN :: (RandomGen g) => Int -> g -> ([g], g)
8 splitN 0 g = ([], g)
9 splitN n g = (g1:l, g')
10 where
11 (l, g') = splitN (n-1) g2
12 (g1, g2) = split g
14 -- The funny splitting operation.
15 split' :: (RandomGen g) => g -> (g, g)
16 split' g = (g12, g21)
17 where
18 (g1, g2) = split g
19 (_, g12) = split g1
20 (g21, _) = split g2
22 -- This test checks if generators created by calling split 2 times are independent.
23 -- It generates pairs of integers from 0 to n-1, using split' to
24 -- generate both numbers using one seed. Then it counts how often the
25 -- two numbers are equal.
26 test :: (RandomGen g) => Int -> Int -> g -> Int
27 test numTests n g = equals
28 where
29 (gs, _) = splitN numTests g
30 equals = count id \$ map single gs
31 count p l = length \$ filter p l
32 single g' = (fst \$ randomR (0, n-1) g1) == (fst \$ randomR (0, n-1) g2)
33 where
34 (g1, g2) = split' g'
36 main = do
37 let g = seedTFGen (42, 42, 42, 42)
38 forM_ [2..15] \$ \i -> do
39 let actual = test (i * 1000) i g
40 putStrLn \$ "Generated " ++ show (i * 1000)
41 ++ " pairs of numbers from 0 to " ++ show (i - 1)
42 ++ " -- " ++ show actual ++ " pairs contained equal numbers "
43 ++ "and we expected about 1000."