random-fu-0.1.3: src/Data/Random/Source.hs
{-
- ``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