scroll-1.20150313: Rand.hs
module Rand (
initRand,
withStdGen,
randM,
randGen,
random,
randomR,
randFrom,
) where
import System.Random
import Control.Applicative
import Control.Monad.State.Strict
import Types
initRand :: (Maybe String) -> IO Rand
initRand Nothing = DefRand <$> getStdGen
initRand (Just "0") = return NoRand
initRand (Just n) = return $ Rand $ mkStdGen $ read n
withStdGen :: Rand -> a -> (StdGen -> a) -> a
withStdGen NoRand d _ = d
withStdGen (Rand r) _ f = f r
withStdGen (DefRand r) _ f = f r
randGen :: Rand -> StdGen
randGen = fst . randGen'
randGen' :: Rand -> (StdGen, StdGen -> Rand)
randGen' (Rand v) = (v, Rand)
randGen' (DefRand v) = (v, DefRand)
randGen' NoRand = (mkStdGen 0, \_ -> NoRand)
randM :: (StdGen -> (v, StdGen)) -> M v
randM f = do
r <- gets randSource
let (g, mk) = randGen' r
let (v, g') = f g
modify $ \s -> s { randSource = mk g' }
return v
randFrom :: [a] -> M a
randFrom l = do
n <- randM $ randomR (0,length l - 1)
return (l !! n)