1module Rand (
2	initRand,
3	withStdGen,
4	randM,
5	randGen,
6	random,
7	randomR,
8	randFrom,
9) where
10
11import System.Random
12import Control.Applicative
13import Control.Monad.State.Strict
14import Prelude
15
16import Types
17
18initRand :: (Maybe String) -> IO Rand
19initRand Nothing = DefRand <$> getStdGen
20initRand (Just "0") = return NoRand
21initRand (Just n) = return $ Rand $ mkStdGen $ read n
22
23withStdGen :: Rand -> a -> (StdGen -> a) -> a
24withStdGen NoRand d _ = d
25withStdGen (Rand r) _ f = f r
26withStdGen (DefRand r) _ f = f r
27
28randGen :: Rand -> StdGen
29randGen = fst . randGen'
30
31randGen' :: Rand -> (StdGen, StdGen -> Rand)
32randGen' (Rand v) = (v, Rand)
33randGen' (DefRand v) = (v, DefRand)
34randGen' NoRand = (mkStdGen 0, \_ -> NoRand)
35
36randM :: (StdGen -> (v, StdGen)) -> M v
37randM f = do
38	r <- gets randSource
39	let (g, mk) = randGen' r
40	let (v, g') = f g
41	modify $ \s -> s { randSource = mk g' }
42	return v
43
44randFrom :: [a] -> M a
45randFrom l = do
46	n <- randM $ randomR (0,length l - 1)
47	return (l !! n)
48