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


-- | 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
class Monad m => RandomSource (m :: * -> *) s
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. <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>In a monad, using a <a>RandomSource</a>:</li>
--   </ul>
--   
--   <pre>
--   runRVar (uniform 1 100) DevRandom :: IO Int
--   </pre>
--   
--   <ul>
--   <li>In a monad, using a <a>MonadRandom</a> instance:</li>
--   </ul>
--   
--   <pre>
--   sampleRVar (uniform 1 100) :: State PureMT Int
--   </pre>
--   
--   <ul>
--   <li>As a pure function transforming a functional RNG:</li>
--   </ul>
--   
--   <pre>
--   sampleState (uniform 1 100) :: StdGen -&gt; (Int, StdGen)
--   </pre>
--   
--   (where <tt>sampleState = runState . sampleRVar</tt>)
type RVar = RVarT Identity

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

-- | <tt>sampleRVar x</tt> is equivalent to <tt>runRVar x
--   <tt>StdRandom</tt></tt>.
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
--   <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 :: RandomSource m s => RVarT m a -> s -> m a
sampleRVarT :: MonadRandom 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 :: RandomSource m s => (forall t. n t -> m t) -> RVarT n a -> s -> m a

-- | <tt>sampleRVarTWith lift x</tt> is equivalent to <tt>runRVarTWith lift
--   x <tt>StdRandom</tt></tt>.
sampleRVarTWith :: 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)
