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