random-fu-0.3.0.0: src/Data/Random/Sample.hs
{-# LANGUAGE
MultiParamTypeClasses,
FlexibleInstances, FlexibleContexts,
IncoherentInstances
#-}
{-# OPTIONS_GHC -fno-warn-simplifiable-class-constraints #-}
module Data.Random.Sample where
import Control.Monad.State
import Control.Monad.Reader
import Data.Random.Distribution
import Data.Random.Lift
import Data.Random.RVar
import System.Random.Stateful
-- |A typeclass allowing 'Distribution's and 'RVar's to be sampled. Both may
-- also be sampled via 'runRVar' or 'runRVarT', but I find it psychologically
-- pleasing to be able to sample both using this function, as they are two
-- separate abstractions for one base concept: a random variable.
class Sampleable d m t where
-- |Directly sample from a distribution or random variable, using the given source of entropy.
sampleFrom :: StatefulGen g m => g -> d t -> m t
instance Distribution d t => Sampleable d m t where
sampleFrom gen d = runRVarT (rvar d) gen
-- This instance overlaps with the other, but because RVarT is not a Distribution there is no conflict.
instance Lift m n => Sampleable (RVarT m) n t where
sampleFrom gen x = runRVarT x gen
-- |Sample a random variable using the default source of entropy for the
-- monad in which the sampling occurs.
sample :: (Sampleable d m t, StatefulGen g m, MonadReader g m) => d t -> m t
sample thing = ask >>= \gen -> sampleFrom gen thing
-- |Sample a random variable in a \"functional\" style. Typical instantiations
-- of @s@ are @System.Random.StdGen@ or @System.Random.Mersenne.Pure64.PureMT@.
-- sample :: (Distribution d a, StatefulGen g m, MonadReader g m) => d t -> m t
-- sample thing gen = runStateGen gen (\stateGen -> sampleFrom stateGen thing)
sampleState :: (Distribution d t, RandomGen g, MonadState g m) => d t -> m t
sampleState thing = sampleFrom StateGenM thing
-- |Sample a random variable in a \"functional\" style. Typical instantiations
-- of @g@ are @System.Random.StdGen@ or @System.Random.Mersenne.Pure64.PureMT@.
samplePure :: (Distribution d t, RandomGen g) => d t -> g -> (t, g)
samplePure thing gen = runStateGen gen (\stateGen -> sampleFrom stateGen thing)