module Random ( RandomGen(next, split), StdGen, mkStdGen, Random( random, randomR, randoms, randomRs, randomIO, randomRIO ), getStdRandom, getStdGen, setStdGen, newStdGen ) where ---------------- The RandomGen class ------------------------ class RandomGen g where next :: g -> (Int, g) split :: g -> (g, g) ---------------- A standard instance of RandomGen ----------- data StdGen = ... -- Abstract instance RandomGen StdGen where ... instance Read StdGen where ... instance Show StdGen where ... mkStdGen :: Int -> StdGen ---------------- The Random class --------------------------- class Random a where randomR :: RandomGen g => (a, a) -> g -> (a, g) random :: RandomGen g => g -> (a, g) randomRs :: RandomGen g => (a, a) -> g -> [a] randoms :: RandomGen g => g -> [a] randomRIO :: (a,a) -> IO a randomIO :: IO a instance Random Int where ... instance Random Integer where ... instance Random Float where ... instance Random Double where ... instance Random Bool where ... instance Random Char where ... ---------------- The global random generator ---------------- newStdGen :: IO StdGen setStdGen :: StdGen -> IO () getStdGen :: IO StdGen getStdRandom :: (StdGen -> (a, StdGen)) -> IO a |
The Random library deals with the common task of pseudo-random number generation. The library makes it possible to generate repeatable results, by starting with a specified initial random number generator; or to get different results on each run by using the system-initialised generator, or by supplying a seed from some other source.
The library is split into two layers:
The class RandomGen provides a common interface to random number generators.
class RandomGen g where
next :: g -> (Int, g)
split :: g -> (g, g)
The Random library provides one instance of RandomGen, the abstract data
type StdGen:
data StdGen = ... -- Abstract
instance RandomGen StdGen where ...
instance Read StdGen where ...
instance Show StdGen where ...
mkStdGen :: Int -> StdGen
The result of repeatedly using next should be at least as
statistically robust as the "Minimal Standard Random Number Generator"
described by [2,3]. Until more is known about implementations of split,
all we require is that split deliver generators that are (a) not identical
and (b) independently robust in the sense just given.
The show/Read instances of StdGen provide a primitive way to save the state of a random number generator. It is required that read (show g) == g.
In addition, read may be used to map an arbitrary string (not necessarily one produced by show) onto a value of type StdGen. In general, the read instance of StdGen has the following properties:
The function mkStdGen provides an alternative way of producing an initial generator, by mapping an Int into a generator. Again, distinct arguments should be likely to produce distinct generators.
Programmers may, of course, supply their own instances of RandomGen.
With a source of random number supply in hand, the Random class allows
the programmer to extract random values of a variety of types:
class Random a where
randomR :: RandomGen g => (a, a) -> g -> (a, g)
random :: RandomGen g => g -> (a, g)
randomRs :: RandomGen g => (a, a) -> g -> [a]
randoms :: RandomGen g => g -> [a]
randomRIO :: (a,a) -> IO a
randomIO :: IO a
-- Default methods
randoms g = x : randoms g'
where
(x,g') = random g
randomRs = ...similar...
randomIO = getStdRandom random
randomRIO range = getStdRandom (randomR range)
instance Random Int where ...
instance Random Integer where ...
instance Random Float where ...
instance Random Double where ...
instance Random Bool where ...
instance Random Char where ...
There is a single, implicit, global random number generator
of type StdGen, held in some global variable maintained by the IO monad.
It is initialised automatically in some system-dependent fashion,
for example, by using the time of day, or Linux's kernal random number generator.
To get deterministic behaviour, use setStdGen.
setStdGen :: StdGen -> IO ()
getStdGen :: IO StdGen
newStdGen :: IO StdGen
getStdRandom :: (StdGen -> (a, StdGen)) -> IO a
The Web site http://random.mat.sbg.ac.at/ is a great source of information.