packages feed

scroll-1.20151219: Rand.hs

module Rand (
	initRand,
	withStdGen,
	randM,
	randGen,
	random,
	randomR,
	randFrom,
) where

import System.Random
import Control.Applicative
import Control.Monad.State.Strict
import Prelude

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)