-- 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.
--   
--   Changes in 0.2.0.1: Version bump for transformers dependency.
@package rvar
@version 0.2.0.6

-- | 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 :: Type -> Type) 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 :: Type -> Type)

-- | Generate a uniformly distributed random Word8
getRandomWord8 :: MonadRandom m => m Word8

-- | Generate a uniformly distributed random Word16
getRandomWord16 :: MonadRandom m => m Word16

-- | Generate a uniformly distributed random Word32
getRandomWord32 :: MonadRandom m => m Word32

-- | Generate a uniformly distributed random Word64
getRandomWord64 :: MonadRandom m => m Word64

-- | Generate a uniformly distributed random Double in the range 0
--   <= U < 1
getRandomDouble :: MonadRandom m => m Double

-- | Generate a uniformly distributed random Integer in the range 0
--   <= U < 256^n
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:
--   
--   
--   
- In a monad, using a RandomSource:
--   
--   
--   
--   runRVar (uniform 1 100) DevRandom :: IO Int
--   
--   
--   
--   
- In a monad, using a MonadRandom instance:
--   
--   
--   
--   sampleRVar (uniform 1 100) :: State PureMT Int
--   
--   
--   
--   
- As a pure function transforming a functional RNG:
--   
--   
--   
--   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 :: forall m n s a. 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 :: forall m n a. MonadRandom m => (forall t. n t -> m t) -> RVarT n a -> m a
instance GHC.Base.Functor (Data.RVar.RVarT n)
instance GHC.Base.Monad (Data.RVar.RVarT n)
instance Data.Random.Internal.Source.MonadRandom (Data.RVar.RVarT n)
instance GHC.Base.Applicative (Data.RVar.RVarT n)
instance Control.Monad.Prompt.MonadPrompt Data.Random.Source.Internal.Prim.Prim (Data.RVar.RVarT n)
instance Control.Monad.Trans.Class.MonadTrans Data.RVar.RVarT
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Data.RVar.RVarT m)
