Prime -> 2010
[haskell-report.git] / report / lib-code / Random.hs
1 module Random (
2 RandomGen(next, split, genRange),
3 StdGen, mkStdGen,
4
5 Random( random, randomR,
6 randoms, randomRs,
7 randomIO, randomRIO ),
8
9 getStdRandom,
10 getStdGen, setStdGen, newStdGen
11 ) where
12
13 ---------------- The RandomGen class ---------------------------
14
15 class RandomGen g where
16 genRange :: g -> (Int, Int)
17 next :: g -> (Int, g)
18 split :: g -> (g, g) -- May not exist for all RandomGens
19
20
21 ---------------- A standard instance of RandomGen ---------------
22 data StdGen = ... -- Abstract
23
24 instance RandomGen StdGen where ...
25
26 -- The show/read instances provide a primitive way to save
27 -- the state of a random number generator
28 -- It is expected read (show g) == g
29
30 instance Read StdGen where ...
31 -- read succeeds on *any* string, not only those
32 -- constructed with show. Hence you can use any
33 -- string as way to construct a RandomGen.
34 -- - read guarantees to consume a finite portion of
35 -- the string
36 -- - different strings are likely to result in
37 -- different generators
38
39 instance Show StdGen where ...
40
41 mkStdGen :: Int -> StdGen
42 -- Make a StdGen from an Int. Different Ints should result
43 -- in different generators.
44
45
46 ---------------- The Random class ---------------------------
47
48 class Random a where
49 randomR :: RandomGen g => (a, a) -> g -> (a, g)
50 -- Returns a random value uniformly distributed in [lo,hi]
51 -- It is unspecified what happens if lo > hi
52
53 random :: RandomGen g => g -> (a, g)
54 -- Return any value of type a.
55 -- For bounded types, the range is normally the whole type
56 -- For Fractional types, the range is normally [0..1]
57 -- For Integer, the range is (arbitrarily) the range of Int
58
59 randomRs :: RandomGen g => (a, a) -> g -> [a]
60 randoms :: RandomGen g => g -> [a]
61
62 randomIO :: IO a
63 randomRIO :: (a,a) -> IO a
64
65 -- Default methods
66 randoms g = x : randoms g'
67 where
68 (x,g') = random g
69 randomRs = ...similar...
70
71 randomIO = getStdRandom random
72 randomRIO range = getStdRandom (randomR range)
73
74
75 instance Random Int where ...
76 instance Random Integer where ...
77 instance Random Float where ...
78 instance Random Double where ...
79 instance Random Bool where ...
80 instance Random Char where ...
81
82
83 ---------------- The global random generator ---------------------------
84
85 -- There is a single, implicit, global random number generator
86 -- of type StdGen, held in some global variable maintained by the IO monad
87 --
88 -- It is initialised non-deterministically; to get
89 -- deterministic behaviour use setStdGen.
90
91 setStdGen :: StdGen -> IO () -- Set the global generator
92 getStdGen :: IO StdGen -- Get the global generator
93
94 getStdRandom :: (StdGen -> (a, StdGen)) -> IO a
95 -- Use the supplied function to get a value from
96 -- the current global random generator, g, and update the
97 -- global generator with the new generator returned
98 getStdRandom f = do
99 g <- getStdGen
100 let (val, g') = f g
101 setStdGen g'
102 return val
103
104 newStdGen :: IO StdGen
105 -- Apply split to the current global random generator
106 -- update it with one of the results and return the other
107 newStdGen = do
108 g <- getStdGen
109 let (s1,s2) = split g
110 setStdGen s1
111 return s2
112
113