-- 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 (<a>RVar</a>) 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 <a>RVar</a> 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 <tt>Distribution</tt> instances - they all
--   are defined in terms of <a>RVar</a>s.
module Data.RVar

-- | An opaque type modeling a "random variable" - a value which depends on
--   the outcome of some random event. <a>RVar</a>s can be conveniently
--   defined by an imperative-looking style:
--   
--   <pre>
--   normalPair =  do
--       u &lt;- stdUniform
--       t &lt;- stdUniform
--       let r = sqrt (-2 * log u)
--           theta = (2 * pi) * t
--   
--           x = r * cos theta
--           y = r * sin theta
--       return (x,y)
--   </pre>
--   
--   OR by a more applicative style:
--   
--   <pre>
--   logNormal = exp &lt;$&gt; stdNormal
--   </pre>
--   
--   Once defined (in any style), there are several ways to sample
--   <a>RVar</a>s:
--   
--   <ul>
--   <li>Using an immutable pseudo-random number generator that has an
--   instance for <a>RandomGen</a> with <a>StateT</a> monad:</li>
--   </ul>
--   
--   <pre>
--   &gt;&gt;&gt; import qualified Data.Random as Fu (uniform)
--   
--   &gt;&gt;&gt; import System.Random (mkStdGen)
--   
--   &gt;&gt;&gt; import Control.Monad.State (runState)
--   
--   &gt;&gt;&gt; runState (sampleStateRVar (Fu.uniform 1 (100 :: Integer))) (mkStdGen 2021)
--   (79,StdGen {unStdGen = SMGen 4687568268719557181 4805600293067301895})
--   </pre>
--   
--   <ul>
--   <li>Using a mutable pseud-random number generator that has an instance
--   for <a>StatefulGen</a> with <a>ReaderT</a> monad.</li>
--   </ul>
--   
--   <pre>
--   &gt;&gt;&gt; import qualified Data.Random as Fu (uniform)
--   
--   &gt;&gt;&gt; import System.Random.MWC (create)
--   
--   &gt;&gt;&gt; import Control.Monad.Reader (runReaderT)
--   
--   &gt;&gt;&gt; import qualified Data.Vector.Storable as VS
--   
--   &gt;&gt;&gt; initialize (VS.singleton 2021) &gt;&gt;= runReaderT (sampleReaderRVar (uniform 1 (100 :: Integer)))
--   8
--   </pre>
type RVar = RVarT Identity

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

-- | <tt>sampleRVar x</tt> is equivalent to <tt>runRVar x
--   <tt>StdRandom</tt></tt>.
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 <a>RandomGen</a> 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
--   <a>RVarT</a> <a>IO</a> value:
--   
--   <pre>
--   rwalkIO :: IO (RVarT IO Double)
--   rwalkIO d = do
--       lastVal &lt;- newIORef 0
--   
--       let x = do
--               prev    &lt;- lift (readIORef lastVal)
--               change  &lt;- rvarT StdNormal
--   
--               let new = prev + change
--               lift (writeIORef lastVal new)
--               return new
--   
--       return x
--   </pre>
--   
--   To run the random walk it must first be initialized, after which it
--   can be sampled as usual:
--   
--   <pre>
--   do
--       rw &lt;- rwalkIO
--       x &lt;- sampleRVarT rw
--       y &lt;- sampleRVarT rw
--       ...
--   </pre>
--   
--   The same random-walk process as above can be implemented using MTL
--   types as follows (using <tt>import Control.Monad.Trans as MTL</tt>):
--   
--   <pre>
--   rwalkState :: RVarT (State Double) Double
--   rwalkState = do
--       prev &lt;- MTL.lift get
--       change  &lt;- rvarT StdNormal
--   
--       let new = prev + change
--       MTL.lift (put new)
--       return new
--   </pre>
--   
--   Invocation is straightforward (although a bit noisy) if you're used to
--   MTL:
--   
--   <pre>
--   rwalk :: Int -&gt; Double -&gt; StdGen -&gt; ([Double], StdGen)
--   rwalk count start gen =
--       flip evalState start .
--           flip runStateT gen .
--               sampleRVarTWith MTL.lift $
--                   replicateM count rwalkState
--   </pre>
data RVarT m 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 <a>RVarT</a>, 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:
--   
--   <pre>
--   lift . return = return
--   lift (x &gt;&gt;= f) = (lift x) &gt;&gt;= (lift . f)
--   </pre>
--   
--   One example of a useful non-standard lifting would be one that takes
--   <tt>State s</tt> to another monad with a different state
--   representation (such as <tt>IO</tt> with the state mapped to an
--   <tt>IORef</tt>):
--   
--   <pre>
--   embedState :: (Monad m) =&gt; m s -&gt; (s -&gt; m ()) -&gt; State s a -&gt; m a
--   embedState get put = \m -&gt; do
--       s &lt;- get
--       (res,s) &lt;- return (runState m s)
--       put s
--       return res
--   </pre>
--   
--   The ability to lift is very important - without it, every <a>RVar</a>
--   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
--   <a>RVar</a> in more than one monad) or functions manipulating
--   <a>RVar</a>s 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

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

-- | <tt>sampleRVarTWith lift x</tt> is equivalent to <tt>runRVarTWith lift
--   x <tt>StdRandom</tt></tt>.
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 :: Uniform a => RVarT m a
uniformRangeRVarT :: UniformRange a => (a, a) -> RVarT m a

-- | A <tt>Prompt</tt> 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 <a>StatefulGen</a> instance for
--   <a>RVarT</a>
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 <a>ShortByteString</a> of length <tt>n</tt>
--   bytes
[PrimShortByteString] :: !Int -> Prim ShortByteString
instance System.Random.Internal.StatefulGen Data.RVar.RGen (Data.RVar.RVarT m)
instance GHC.Base.Functor (Data.RVar.RVarT n)
instance GHC.Base.Monad (Data.RVar.RVarT n)
instance GHC.Base.Applicative (Data.RVar.RVarT n)
instance Control.Monad.Prompt.MonadPrompt Data.RVar.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)
