{- - ``Data/Random/Source'' -} {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, GADTs #-} module Data.Random.Source ( MonadRandom(..) , RandomSource(..) , Prim(..) ) where import Data.Word import Data.Random.Internal.Primitives -- |A typeclass for monads with a chosen source of entropy. For example, -- 'RVar' is such a monad - the source from which it is (eventually) sampled -- is the only source from which a random variable is permitted to draw, so -- when directly requesting entropy for a random variable these functions -- are used. -- -- Occasionally one might want a 'RandomSource' specifying the 'MonadRandom' -- instance (for example, when using 'runRVar'). For those cases, -- "Data.Random.Source.Std".'StdRandom' provides a 'RandomSource' that -- maps to the 'MonadRandom' instance. -- -- For example, @State StdGen@ has a 'MonadRandom' instance, so to run an -- 'RVar' (called @x@ in this example) in this monad one could write -- @runRVar x StdRandom@ (or more concisely with the 'sample' function: @sample x@). -- class Monad m => MonadRandom m where -- |Generate a random value corresponding to the specified primitive. -- The 'Prim' type has many variants, and is also somewhat unstable. -- 'getPrimWhere' is a useful function for abstracting over the type, -- semi-automatically extending a partial implementation to the full -- 'Prim' type. getRandomPrim :: Prim t -> m t -- |A source of entropy which can be used in the given monad. -- -- See also 'MonadRandom'. class Monad m => RandomSource m s where -- |Generate a random value corresponding to the specified primitive. -- The 'Prim' type has many variants, and is also somewhat unstable. -- 'getPrimWhere' is a useful function for abstracting over the type, -- semi-automatically extending a partial implementation to the full -- 'Prim' type. getRandomPrimFrom :: s -> Prim t -> m t instance Monad m => RandomSource m (m Word8) where getRandomPrimFrom f = getPrimWhere supported (getPrim f) where supported :: Prim a -> Bool supported PrimWord8 = True supported _ = False getPrim :: m Word8 -> Prim a -> m a getPrim f PrimWord8 = f instance Monad m => RandomSource m (m Word16) where getRandomPrimFrom f = getPrimWhere supported (getPrim f) where supported :: Prim a -> Bool supported PrimWord16 = True supported _ = False getPrim :: m Word16 -> Prim a -> m a getPrim f PrimWord16 = f instance Monad m => RandomSource m (m Word32) where getRandomPrimFrom f = getPrimWhere supported (getPrim f) where supported :: Prim a -> Bool supported PrimWord32 = True supported _ = False getPrim :: m Word32 -> Prim a -> m a getPrim f PrimWord32 = f instance Monad m => RandomSource m (m Word64) where getRandomPrimFrom f = getPrimWhere supported (getPrim f) where supported :: Prim a -> Bool supported PrimWord64 = True supported _ = False getPrim :: m Word64 -> Prim a -> m a getPrim f PrimWord64 = f instance Monad m => RandomSource m (m Double) where getRandomPrimFrom f = getPrimWhere supported (getPrim f) where supported :: Prim a -> Bool supported PrimDouble = True supported _ = False getPrim :: m Double -> Prim a -> m a getPrim f PrimDouble = f