{-# OPTIONS -fglasgow-exts #-} module Control.Monad.Random ( Rand , runRand , evalRand , RandT , runRandT , evalRandT , MonadRandom(..) ) where import System.Random import Control.Monad import Control.Monad.State class RandomGen g => MonadRandom m g | m -> g where getRandom :: Random a => m a getRandomR :: Random a => (a, a) -> m a newtype Rand g a = R{ unR :: State g a } deriving (Functor, Monad, MonadFix) runRand :: RandomGen g => Rand g a -> g -> (a, g) runRand = runState . unR evalRand :: RandomGen g => Rand g a -> g -> a evalRand = evalState . unR instance RandomGen g => MonadRandom (Rand g) g where getRandom = R $ State $ random getRandomR range = R $ State $ randomR range newtype RandT g m a = RT{ unRT :: StateT g m a } deriving (Functor, Monad, MonadFix, MonadTrans, MonadIO, MonadPlus) runRandT :: (Monad m, RandomGen g) => RandT g m a -> g -> m (a, g) runRandT = runStateT . unRT evalRandT :: (Monad m, RandomGen g) => RandT g m a -> g -> m a evalRandT = evalStateT . unRT instance (Monad m, RandomGen g) => MonadRandom (RandT g m) g where getRandom = RT $ StateT $ return . random getRandomR range = RT $ StateT $ return . randomR range