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