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


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

-- | A source of entropy which can be used in the given monad.
--   
--   See also <a>MonadRandom</a>.
--   
--   Minimum implementation is either the internal <a>getRandomPrimFrom</a>
--   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 <tt>randomSource</tt> 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 <tt>randomSource</tt>, 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):
--   
--   <pre>
--   $(randomSource [d|
--           instance RandomSource FooM Bar where
--               {- at least one RandomSource function... -}
--       |])
--   </pre>
class Monad m => RandomSource (m :: Type -> Type) s

-- | A typeclass for monads with a chosen source of entropy. For example,
--   <tt>RVar</tt> 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 <a>getRandomPrim</a> 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 <tt>monadRandom</tt> 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 <tt>monadRandom</tt>, just wrap your instance declaration as
--   follows (and enable the TemplateHaskell and GADTs language
--   extensions):
--   
--   <pre>
--   $(monadRandom [d|
--           instance MonadRandom FooM where
--               getRandomDouble = return pi
--               getRandomWord16 = return 4
--               {- etc... -}
--       |])
--   </pre>
class Monad m => MonadRandom (m :: Type -> Type)

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

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

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

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

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

-- | Generate a uniformly distributed random <a>Integer</a> in the range 0
--   &lt;= U &lt; 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. <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 :: forall m n s a. 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 :: 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)
