-- 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.3.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

-- | 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:
--   
--   
--   
- Using an immutable pseudo-random number generator that has an
--   instance for RandomGen with StateT monad:
--   
--   
--   
--   >>> import qualified Data.Random as Fu (uniform)
--   
--   >>> import System.Random (mkStdGen)
--   
--   >>> import Control.Monad.State (runState)
--   
--   >>> runState (sampleStateRVar (Fu.uniform 1 (100 :: Integer))) (mkStdGen 2021)
--   (79,StdGen {unStdGen = SMGen 4687568268719557181 4805600293067301895})
--   
--   
--   
--   
- Using a mutable pseud-random number generator that has an instance
--   for StatefulGen with ReaderT monad.
--   
--   
--   
--   >>> import qualified Data.Random as Fu (uniform)
--   
--   >>> import System.Random.MWC (create)
--   
--   >>> import Control.Monad.Reader (runReaderT)
--   
--   >>> import qualified Data.Vector.Storable as VS
--   
--   >>> initialize (VS.singleton 2021) >>= runReaderT (sampleReaderRVar (uniform 1 (100 :: Integer)))
--   8
--   
type RVar = RVarT Identity

-- | "Run" an RVar - samples the random variable from the provided
--   source of entropy.
runRVar :: StatefulGen g m => RVar a -> g -> m a

-- | sampleRVar x is equivalent to runRVar x
--   StdRandom.
sampleReaderRVar :: (StatefulGen g m, MonadReader g m) => RVar a -> m a
sampleStateRVar :: (RandomGen g, MonadState g m) => RVar a -> m a

-- | Sample random variable using RandomGen generator as source of
--   entropy
pureRVar :: RandomGen g => RVar a -> g -> (a, g)

-- | 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 :: Type -> Type) a
runRVarT :: StatefulGen g m => RVarT m a -> g -> m a
sampleReaderRVarT :: (StatefulGen g m, MonadReader g m) => RVarT m a -> m a
sampleStateRVarT :: (RandomGen g, MonadState g 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 g a. StatefulGen g m => (forall t. () => n t -> m t) -> RVarT n a -> g -> m a

-- | sampleRVarTWith lift x is equivalent to runRVarTWith lift
--   x StdRandom.
sampleReaderRVarTWith :: forall m n a g. (StatefulGen g m, MonadReader g m) => (forall t. () => n t -> m t) -> RVarT n a -> m a

-- | sampleRVarTWith lift x is equivalent to runRVarTWith lift
--   x StdRandom.
sampleStateRVarTWith :: forall m n a g. (RandomGen g, MonadState g m) => (forall t. () => n t -> m t) -> RVarT n a -> m a
data RGen
RGen :: RGen
uniformRVarT :: forall a (m :: Type -> Type). Uniform a => RVarT m a
uniformRangeRVarT :: forall a (m :: Type -> Type). UniformRange a => (a, a) -> RVarT m a

-- | A Prompt GADT describing a request for a primitive random
--   variate. Random variable definitions will request their entropy via
--   these prompts, and entropy sources will satisfy those requests. This
--   data type is needed for creating StatefulGen instance for
--   RVarT
data Prim a

-- | An unsigned byte, uniformly distributed from 0 to 0xff
[PrimWord8] :: Prim Word8

-- | An unsigned 16-bit word, uniformly distributed from 0 to 0xffff
[PrimWord16] :: Prim Word16

-- | An unsigned 32-bit word, uniformly distributed from 0 to 0xffffffff
[PrimWord32] :: Prim Word32

-- | An unsigned 64-bit word, uniformly distributed from 0 to
--   0xffffffffffffffff
[PrimWord64] :: Prim Word64

-- | A uniformly distributed ShortByteString of length n
--   bytes
[PrimShortByteString] :: !Int -> Prim ShortByteString
instance GHC.Internal.Base.Applicative (Data.RVar.RVarT n)
instance GHC.Internal.Base.Functor (Data.RVar.RVarT n)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Data.RVar.RVarT m)
instance Control.Monad.Prompt.MonadPrompt Data.RVar.Prim.Prim (Data.RVar.RVarT n)
instance GHC.Internal.Base.Monad (Data.RVar.RVarT n)
instance Control.Monad.Trans.Class.MonadTrans Data.RVar.RVarT
instance System.Random.Internal.StatefulGen Data.RVar.RGen (Data.RVar.RVarT m)
