-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Random Variables -- -- Random number generation based on modeling random variables by an -- abstract type (RVar) which can be composed and manipulated -- monadically and sampled in either monadic or "pure" styles. The -- primary purpose of this library is to support defining and sampling a -- wide variety of high quality random variables. Quality is prioritized -- over speed, but performance is an important goal too. In my testing, I -- have found it capable of speed comparable to other Haskell libraries, -- but still a fair bit slower than straight C implementations of the -- same algorithms. @package rvar @version 0.2 -- | Random variables. An RVar is a sampleable random variable. -- Because probability distributions form a monad, they are quite easy to -- work with in the standard Haskell monadic styles. For examples, see -- the source for any of the Distribution instances - they all -- are defined in terms of RVars. module Data.RVar -- | A source of entropy which can be used in the given monad. -- -- See also MonadRandom. -- -- Minimum implementation is either the internal getRandomPrimFrom -- or all other functions. Additionally, this class's interface is -- subject to extension at any time, so it is very, very strongly -- recommended that the randomSource Template Haskell function -- be used to implement this function rather than directly implementing -- it. That function takes care of choosing default implementations for -- any missing functions; as long as at least one function is -- implemented, it will derive sensible implementations of all others. -- -- To use randomSource, just wrap your instance declaration as -- follows (and enable the TemplateHaskell, MultiParamTypeClasses and -- GADTs language extensions, as well as any others required by your -- instances, such as FlexibleInstances): -- --
--   $(randomSource [d|
--           instance RandomSource FooM Bar where
--               {- at least one RandomSource function... -}
--       |])
--   
class Monad m => RandomSource m :: (* -> *) s -- | 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. -- -- Minimum implementation is either the internal getRandomPrim or -- all other functions. Additionally, this class's interface is subject -- to extension at any time, so it is very, very strongly recommended -- that the monadRandom Template Haskell function be used to -- implement this function rather than directly implementing it. That -- function takes care of choosing default implementations for any -- missing functions; as long as at least one function is implemented, it -- will derive sensible implementations of all others. -- -- To use monadRandom, just wrap your instance declaration as -- follows (and enable the TemplateHaskell and GADTs language -- extensions): -- --
--   $(monadRandom [d|
--           instance MonadRandom FooM where
--               getRandomDouble = return pi
--               getRandomWord16 = return 4
--               {- etc... -}
--       |])
--   
class Monad m => MonadRandom m :: (* -> *) getRandomWord8 :: MonadRandom m => m Word8 getRandomWord16 :: MonadRandom m => m Word16 getRandomWord32 :: MonadRandom m => m Word32 getRandomWord64 :: MonadRandom m => m Word64 getRandomDouble :: MonadRandom m => m Double getRandomNByteInteger :: MonadRandom m => Int -> m Integer -- | An opaque type modeling a "random variable" - a value which depends on -- the outcome of some random event. RVars can be conveniently -- defined by an imperative-looking style: -- --
--   normalPair =  do
--       u <- stdUniform
--       t <- stdUniform
--       let r = sqrt (-2 * log u)
--           theta = (2 * pi) * t
--           
--           x = r * cos theta
--           y = r * sin theta
--       return (x,y)
--   
-- -- OR by a more applicative style: -- --
--   logNormal = exp <$> stdNormal
--   
-- -- Once defined (in any style), there are several ways to sample -- RVars: -- -- -- --
--   runRVar (uniform 1 100) DevRandom :: IO Int
--   
-- -- -- --
--   sampleRVar (uniform 1 100) :: State PureMT Int
--   
-- -- -- --
--   sampleState (uniform 1 100) :: StdGen -> (Int, StdGen)
--   
-- -- (where sampleState = runState . sampleRVar) type RVar = RVarT Identity -- | "Run" an RVar - samples the random variable from the provided -- source of entropy. runRVar :: RandomSource m s => RVar a -> s -> m a -- | sampleRVar x is equivalent to runRVar x -- StdRandom. sampleRVar :: MonadRandom m => RVar a -> m a -- | A random variable with access to operations in an underlying monad. -- Useful examples include any form of state for implementing random -- processes with hysteresis, or writer monads for implementing tracing -- of complicated algorithms. -- -- For example, a simple random walk can be implemented as an -- RVarT IO value: -- --
--   rwalkIO :: IO (RVarT IO Double)
--   rwalkIO d = do
--       lastVal <- newIORef 0
--       
--       let x = do
--               prev    <- lift (readIORef lastVal)
--               change  <- rvarT StdNormal
--               
--               let new = prev + change
--               lift (writeIORef lastVal new)
--               return new
--           
--       return x
--   
-- -- To run the random walk it must first be initialized, after which it -- can be sampled as usual: -- --
--   do
--       rw <- rwalkIO
--       x <- sampleRVarT rw
--       y <- sampleRVarT rw
--       ...
--   
-- -- The same random-walk process as above can be implemented using MTL -- types as follows (using import Control.Monad.Trans as MTL): -- --
--   rwalkState :: RVarT (State Double) Double
--   rwalkState = do
--       prev <- MTL.lift get
--       change  <- rvarT StdNormal
--       
--       let new = prev + change
--       MTL.lift (put new)
--       return new
--   
-- -- Invocation is straightforward (although a bit noisy) if you're used to -- MTL: -- --
--   rwalk :: Int -> Double -> StdGen -> ([Double], StdGen)
--   rwalk count start gen = 
--       flip evalState start .
--           flip runStateT gen .
--               sampleRVarTWith MTL.lift $
--                   replicateM count rwalkState
--   
data RVarT m a runRVarT :: RandomSource m s => RVarT m a -> s -> m a sampleRVarT :: MonadRandom m => RVarT m a -> m a -- | "Runs" an RVarT, sampling the random variable it defines. -- -- The first argument lifts the base monad into the sampling monad. This -- operation must obey the "monad transformer" laws: -- --
--   lift . return = return
--   lift (x >>= f) = (lift x) >>= (lift . f)
--   
-- -- One example of a useful non-standard lifting would be one that takes -- State s to another monad with a different state -- representation (such as IO with the state mapped to an -- IORef): -- --
--   embedState :: (Monad m) => m s -> (s -> m ()) -> State s a -> m a
--   embedState get put = \m -> do
--       s <- get
--       (res,s) <- return (runState m s)
--       put s
--       return res
--   
-- -- The ability to lift is very important - without it, every RVar -- would have to either be given access to the full capability of the -- monad in which it will eventually be sampled (which, incidentally, -- would also have to be monomorphic so you couldn't sample one -- RVar in more than one monad) or functions manipulating -- RVars would have to use higher-ranked types to enforce the same -- kind of isolation and polymorphism. runRVarTWith :: RandomSource m s => (forall t. n t -> m t) -> RVarT n a -> s -> m a -- | sampleRVarTWith lift x is equivalent to runRVarTWith lift -- x StdRandom. sampleRVarTWith :: MonadRandom m => (forall t. n t -> m t) -> RVarT n a -> m a instance MonadIO m => MonadIO (RVarT m) instance MonadTrans RVarT instance MonadPrompt Prim (RVarT n) instance Applicative (RVarT n) instance MonadRandom (RVarT n) instance Monad (RVarT n) instance Functor (RVarT n)