-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Random-number generation monad.
--   
--   Support for computations which consume random values.
@package MonadRandom
@version 0.5.3


-- | The <a>MonadRandom</a>, <a>MonadSplit</a>, and <a>MonadInterleave</a>
--   classes.
--   
--   <ul>
--   <li><a>MonadRandom</a> abstracts over monads with the capability of
--   generating random values.</li>
--   <li><a>MonadSplit</a> abstracts over random monads with the ability to
--   get a split generator state. It is not very useful but kept here for
--   backwards compatibility.</li>
--   <li><a>MonadInterleave</a> abstracts over random monads supporting an
--   <a>interleave</a> operation, which allows sequencing computations
--   which do not depend on each other's random generator state, by
--   splitting the generator between them.</li>
--   </ul>
--   
--   This module also defines convenience functions for sampling from a
--   given collection of values, either uniformly or according to given
--   weights.
module Control.Monad.Random.Class

-- | With a source of random number supply in hand, the <a>MonadRandom</a>
--   class allows the programmer to extract random values of a variety of
--   types.
class (Monad m) => MonadRandom m

-- | Takes a range <i>(lo,hi)</i> and a random number generator <i>g</i>,
--   and returns a computation that returns a random value uniformly
--   distributed in the closed interval <i>[lo,hi]</i>, together with a new
--   generator. It is unspecified what happens if <i>lo&gt;hi</i>. For
--   continuous types there is no requirement that the values <i>lo</i> and
--   <i>hi</i> are ever produced, but they may be, depending on the
--   implementation and the interval.
--   
--   See <a>randomR</a> for details.
getRandomR :: (MonadRandom m, Random a) => (a, a) -> m a

-- | The same as <a>getRandomR</a>, but using a default range determined by
--   the type:
--   
--   <ul>
--   <li>For bounded types (instances of <a>Bounded</a>, such as
--   <a>Char</a>), the range is normally the whole type.</li>
--   <li>For fractional types, the range is normally the semi-closed
--   interval <tt>[0,1)</tt>.</li>
--   <li>For <a>Integer</a>, the range is (arbitrarily) the range of
--   <a>Int</a>.</li>
--   </ul>
--   
--   See <a>random</a> for details.
getRandom :: (MonadRandom m, Random a) => m a

-- | Plural variant of <a>getRandomR</a>, producing an infinite list of
--   random values instead of returning a new generator.
--   
--   See <a>randomRs</a> for details.
getRandomRs :: (MonadRandom m, Random a) => (a, a) -> m [a]

-- | Plural variant of <a>getRandom</a>, producing an infinite list of
--   random values instead of returning a new generator.
--   
--   See <a>randoms</a> for details.
getRandoms :: (MonadRandom m, Random a) => m [a]

-- | The class <a>MonadSplit</a> proivides a way to specify a random number
--   generator that can be split into two new generators.
--   
--   This class is not very useful in practice: typically, one cannot
--   actually do anything with a generator. It remains here to avoid
--   breaking existing code unnecessarily. For a more practically useful
--   interface, see <a>MonadInterleave</a>.
class (Monad m) => MonadSplit g m | m -> g

-- | The <a>getSplit</a> operation allows one to obtain two distinct random
--   number generators.
--   
--   See <a>split</a> for details.
getSplit :: MonadSplit g m => m g

-- | The class <a>MonadInterleave</a> proivides a convenient interface atop
--   a <tt>split</tt> operation on a random generator.
class MonadRandom m => MonadInterleave m

-- | If <tt>x :: m a</tt> is a computation in some random monad, then
--   <tt>interleave x</tt> works by splitting the generator, running
--   <tt>x</tt> using one half, and using the other half as the final
--   generator state of <tt>interleave x</tt> (replacing whatever the final
--   generator state otherwise would have been). This means that
--   computation needing random values which comes after <tt>interleave
--   x</tt> does not necessarily depend on the computation of <tt>x</tt>.
--   For example:
--   
--   <pre>
--   &gt;&gt;&gt; evalRandIO $ snd &lt;$&gt; ((,) &lt;$&gt; undefined &lt;*&gt; getRandom)
--   *** Exception: Prelude.undefined
--   &gt;&gt;&gt; evalRandIO $ snd &lt;$&gt; ((,) &lt;$&gt; interleave undefined &lt;*&gt; getRandom)
--   6192322188769041625
--   </pre>
--   
--   This can be used, for example, to allow random computations to run in
--   parallel, or to create lazy infinite structures of random values. In
--   the example below, the infinite tree <tt>randTree</tt> cannot be
--   evaluated lazily: even though it is cut off at two levels deep by
--   <tt>hew 2</tt>, the random value in the right subtree still depends on
--   generation of all the random values in the (infinite) left subtree,
--   even though they are ultimately unneeded. Inserting a call to
--   <tt>interleave</tt>, as in <tt>randTreeI</tt>, solves the problem: the
--   generator splits at each <tt>Node</tt>, so random values in the left
--   and right subtrees are generated independently.
--   
--   <pre>
--   data Tree = Leaf | Node Int Tree Tree deriving Show
--   
--   hew :: Int -&gt; Tree -&gt; Tree
--   hew 0 _    = Leaf
--   hew _ Leaf = Leaf
--   hew n (Node x l r) = Node x (hew (n-1) l) (hew (n-1) r)
--   
--   randTree :: Rand StdGen Tree
--   randTree = Node &lt;$&gt; getRandom &lt;*&gt; randTree &lt;*&gt; randTree
--   
--   randTreeI :: Rand StdGen Tree
--   randTreeI = interleave $ Node &lt;$&gt; getRandom &lt;*&gt; randTreeI &lt;*&gt; randTreeI
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; hew 2 &lt;$&gt; evalRandIO randTree
--   Node 2168685089479838995 (Node (-1040559818952481847) Leaf Leaf) (Node ^CInterrupted.
--   &gt;&gt;&gt; hew 2 &lt;$&gt; evalRandIO randTreeI
--   Node 8243316398511136358 (Node 4139784028141790719 Leaf Leaf) (Node 4473998613878251948 Leaf Leaf)
--   </pre>
interleave :: MonadInterleave m => m a -> m a

-- | Sample a random value from a weighted list. The list must be non-empty
--   and the total weight must be non-zero.
fromList :: MonadRandom m => [(a, Rational)] -> m a

-- | Sample a random value from a weighted list. Return <tt>Nothing</tt> if
--   the list is empty or the total weight is nonpositive.
fromListMay :: MonadRandom m => [(a, Rational)] -> m (Maybe a)

-- | Sample a value uniformly from a nonempty collection of elements.
uniform :: (Foldable t, MonadRandom m) => t a -> m a

-- | Sample a value uniformly from a collection of elements. Return
--   <tt>Nothing</tt> if the collection is empty.
uniformMay :: (Foldable t, MonadRandom m) => t a -> m (Maybe a)

-- | Sample a random value from a weighted nonempty collection of elements.
--   Crashes with a call to <tt>error</tt> if the collection is empty or
--   the total weight is zero.
weighted :: (Foldable t, MonadRandom m) => t (a, Rational) -> m a

-- | Sample a random value from a weighted collection of elements. Returns
--   <tt>Nothing</tt> if the collection is empty or the total weight is
--   zero.
weightedMay :: (Foldable t, MonadRandom m) => t (a, Rational) -> m (Maybe a)
instance Control.Monad.Random.Class.MonadInterleave m => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.Cont.ContT r m)
instance (Control.Monad.Trans.Error.Error e, Control.Monad.Random.Class.MonadInterleave m) => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.Error.ErrorT e m)
instance Control.Monad.Random.Class.MonadInterleave m => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.Except.ExceptT e m)
instance Control.Monad.Random.Class.MonadInterleave m => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.Identity.IdentityT m)
instance Control.Monad.Random.Class.MonadInterleave m => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.List.ListT m)
instance Control.Monad.Random.Class.MonadInterleave m => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.Maybe.MaybeT m)
instance (GHC.Base.Monoid w, Control.Monad.Random.Class.MonadInterleave m) => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
instance (GHC.Base.Monoid w, Control.Monad.Random.Class.MonadInterleave m) => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.RWS.Strict.RWST r w s m)
instance Control.Monad.Random.Class.MonadInterleave m => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.Reader.ReaderT r m)
instance Control.Monad.Random.Class.MonadInterleave m => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.State.Lazy.StateT s m)
instance Control.Monad.Random.Class.MonadInterleave m => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.State.Strict.StateT s m)
instance (GHC.Base.Monoid w, Control.Monad.Random.Class.MonadInterleave m) => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.Writer.Lazy.WriterT w m)
instance (GHC.Base.Monoid w, Control.Monad.Random.Class.MonadInterleave m) => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.Writer.Strict.WriterT w m)
instance Control.Monad.Random.Class.MonadSplit System.Random.Internal.StdGen GHC.Types.IO
instance Control.Monad.Random.Class.MonadSplit g m => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.Cont.ContT r m)
instance (Control.Monad.Trans.Error.Error e, Control.Monad.Random.Class.MonadSplit g m) => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.Error.ErrorT e m)
instance Control.Monad.Random.Class.MonadSplit g m => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.Except.ExceptT e m)
instance Control.Monad.Random.Class.MonadSplit g m => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.Identity.IdentityT m)
instance Control.Monad.Random.Class.MonadSplit g m => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.List.ListT m)
instance Control.Monad.Random.Class.MonadSplit g m => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.Maybe.MaybeT m)
instance (GHC.Base.Monoid w, Control.Monad.Random.Class.MonadSplit g m) => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
instance (GHC.Base.Monoid w, Control.Monad.Random.Class.MonadSplit g m) => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.RWS.Strict.RWST r w s m)
instance Control.Monad.Random.Class.MonadSplit g m => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.Reader.ReaderT r m)
instance Control.Monad.Random.Class.MonadSplit g m => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.State.Lazy.StateT s m)
instance Control.Monad.Random.Class.MonadSplit g m => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.State.Strict.StateT s m)
instance (GHC.Base.Monoid w, Control.Monad.Random.Class.MonadSplit g m) => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.Writer.Lazy.WriterT w m)
instance (GHC.Base.Monoid w, Control.Monad.Random.Class.MonadSplit g m) => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.Writer.Strict.WriterT w m)
instance Control.Monad.Random.Class.MonadRandom GHC.Types.IO
instance Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.Cont.ContT r m)
instance (Control.Monad.Trans.Error.Error e, Control.Monad.Random.Class.MonadRandom m) => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.Error.ErrorT e m)
instance Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.Except.ExceptT e m)
instance Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.Identity.IdentityT m)
instance Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.List.ListT m)
instance Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.Maybe.MaybeT m)
instance (GHC.Base.Monoid w, Control.Monad.Random.Class.MonadRandom m) => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
instance (GHC.Base.Monoid w, Control.Monad.Random.Class.MonadRandom m) => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.RWS.Strict.RWST r w s m)
instance Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.Reader.ReaderT r m)
instance Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.State.Lazy.StateT s m)
instance Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.State.Strict.StateT s m)
instance (Control.Monad.Random.Class.MonadRandom m, GHC.Base.Monoid w) => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.Writer.Lazy.WriterT w m)
instance (Control.Monad.Random.Class.MonadRandom m, GHC.Base.Monoid w) => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.Writer.Strict.WriterT w m)


-- | Strict random monads, passing a random number generator through a
--   computation. See below for examples.
--   
--   In this version, sequencing of computations is strict (but
--   computations are not strict in the state unless you force it with seq
--   or the like). For a lazy version with the same interface, see
--   <a>Control.Monad.Trans.Random.Lazy</a>.
module Control.Monad.Trans.Random.Strict

-- | A random monad parameterized by the type <tt>g</tt> of the generator
--   to carry.
--   
--   The <a>return</a> function leaves the generator unchanged, while
--   <a>&gt;&gt;=</a> uses the final generator of the first computation as
--   the initial generator of the second.
type Rand g = RandT g Identity

-- | Construct a random monad computation from a function. (The inverse of
--   <a>runRand</a>.)
liftRand :: (g -> (a, g)) -> Rand g a

-- | Unwrap a random monad computation as a function. (The inverse of
--   <a>liftRand</a>.)
runRand :: Rand g a -> g -> (a, g)

-- | Evaluate a random computation with the given initial generator and
--   return the final value, discarding the final generator.
--   
--   <ul>
--   <li><pre><a>evalRand</a> m s = fst (<a>runRand</a> m s)</pre></li>
--   </ul>
evalRand :: Rand g a -> g -> a

-- | Evaluate a random computation with the given initial generator and
--   return the final generator, discarding the final value.
--   
--   <ul>
--   <li><pre><a>execRand</a> m s = snd (<a>runRand</a> m s)</pre></li>
--   </ul>
execRand :: Rand g a -> g -> g

-- | Map both the return value and final generator of a computation using
--   the given function.
--   
--   <ul>
--   <li><pre><a>runRand</a> (<a>mapRand</a> f m) = f . <a>runRand</a>
--   m</pre></li>
--   </ul>
mapRand :: ((a, g) -> (b, g)) -> Rand g a -> Rand g b

-- | <tt><a>withRand</a> f m</tt> executes action <tt>m</tt> on a generator
--   modified by applying <tt>f</tt>.
--   
--   <ul>
--   <li><pre><a>withRand</a> f m = <a>modify</a> f &gt;&gt; m</pre></li>
--   </ul>
withRand :: (g -> g) -> Rand g a -> Rand g a

-- | Evaluate a random computation in the <a>IO</a> monad, splitting the
--   global standard generator to get a new one for the computation.
evalRandIO :: Rand StdGen a -> IO a

-- | A random transformer monad parameterized by:
--   
--   <ul>
--   <li><tt>g</tt> - The generator.</li>
--   <li><tt>m</tt> - The inner monad.</li>
--   </ul>
--   
--   The <a>return</a> function leaves the generator unchanged, while
--   <a>&gt;&gt;=</a> uses the final generator of the first computation as
--   the initial generator of the second.
data RandT g m a

-- | Construct a random monad computation from an impure function. (The
--   inverse of <a>runRandT</a>.)
liftRandT :: (g -> m (a, g)) -> RandT g m a

-- | Unwrap a random monad computation as an impure function. (The inverse
--   of <a>liftRandT</a>.)
runRandT :: RandT g m a -> g -> m (a, g)

-- | Evaluate a random computation with the given initial generator and
--   return the final value, discarding the final generator.
--   
--   <ul>
--   <li><pre><a>evalRandT</a> m g = liftM fst (<a>runRandT</a> m
--   g)</pre></li>
--   </ul>
evalRandT :: Monad m => RandT g m a -> g -> m a

-- | Evaluate a random computation with the given initial generator and
--   return the final generator, discarding the final value.
--   
--   <ul>
--   <li><pre><a>execRandT</a> m g = liftM snd (<a>runRandT</a> m
--   g)</pre></li>
--   </ul>
execRandT :: Monad m => RandT g m a -> g -> m g

-- | Map both the return value and final generator of a computation using
--   the given function.
--   
--   <ul>
--   <li><pre><a>runRandT</a> (<a>mapRandT</a> f m) = f . <a>runRandT</a>
--   m</pre></li>
--   </ul>
mapRandT :: (m (a, g) -> n (b, g)) -> RandT g m a -> RandT g n b

-- | <tt><a>withRandT</a> f m</tt> executes action <tt>m</tt> on a
--   generator modified by applying <tt>f</tt>.
--   
--   <ul>
--   <li><pre><a>withRandT</a> f m = <a>modify</a> f &gt;&gt; m</pre></li>
--   </ul>
withRandT :: (g -> g) -> RandT g m a -> RandT g m a

-- | Evaluate a random computation that is embedded in the <a>IO</a> monad,
--   splitting the global standard generator to get a new one for the
--   computation.
evalRandTIO :: MonadIO m => RandT StdGen m a -> m a

-- | Uniform lifting of a <tt>callCC</tt> operation to the new monad. This
--   version rolls back to the original state on entering the continuation.
liftCallCC :: CallCC m (a, g) (b, g) -> CallCC (RandT g m) a b

-- | In-situ lifting of a <tt>callCC</tt> operation to the new monad. This
--   version uses the current state on entering the continuation. It does
--   not satisfy the uniformity property (see
--   <a>Control.Monad.Signatures</a>).
liftCallCC' :: CallCC m (a, g) (b, g) -> CallCC (RandT g m) a b

-- | Lift a <tt>catchE</tt> operation to the new monad.
liftCatch :: Catch e m (a, g) -> Catch e (RandT g m) a

-- | Lift a <tt>listen</tt> operation to the new monad.
liftListen :: Monad m => Listen w m (a, g) -> Listen w (RandT g m) a

-- | Lift a <tt>pass</tt> operation to the new monad.
liftPass :: Monad m => Pass w m (a, g) -> Pass w (RandT g m) a

-- | A proxy that carries information about the type of generator to use
--   with <tt>RandT</tt> monad and its <a>StatefulGen</a> instance.
data RandGen g
RandGen :: RandGen g

-- | A <a>RandT</a> runner that allows using it with <a>StatefulGen</a>
--   restricted actions. Returns the outcome of random computation and the
--   new pseudo-random-number generator
--   
--   <pre>
--   &gt;&gt;&gt; withRandGen (mkStdGen 2021) uniformM :: IO (Int, StdGen)
--   (6070831465987696718,StdGen {unStdGen = SMGen 4687568268719557181 4805600293067301895})
--   </pre>
withRandGen :: g -> (RandGen g -> RandT g m a) -> m (a, g)

-- | Same as <a>withRandGen</a>, but discards the resulting generator.
--   
--   <pre>
--   &gt;&gt;&gt; withRandGen_ (mkStdGen 2021) uniformM :: IO Int
--   6070831465987696718
--   </pre>
withRandGen_ :: Monad m => g -> (RandGen g -> RandT g m a) -> m a
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Control.Monad.Trans.Random.Strict.RandT g m)
instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Control.Monad.Trans.Random.Strict.RandT g m)
instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Control.Monad.Trans.Random.Strict.RandT g m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Monad.Trans.Random.Strict.RandT g m)
instance Control.Monad.Trans.Class.MonadTrans (Control.Monad.Trans.Random.Strict.RandT g)
instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Control.Monad.Trans.Random.Strict.RandT g m)
instance GHC.Base.Monad m => GHC.Base.Monad (Control.Monad.Trans.Random.Strict.RandT g m)
instance GHC.Base.MonadPlus m => GHC.Base.Alternative (Control.Monad.Trans.Random.Strict.RandT g m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Control.Monad.Trans.Random.Strict.RandT g m)
instance GHC.Base.Functor m => GHC.Base.Functor (Control.Monad.Trans.Random.Strict.RandT g m)
instance (GHC.Base.Monad m, System.Random.Internal.RandomGen g) => System.Random.Internal.StatefulGen (Control.Monad.Trans.Random.Strict.RandGen g) (Control.Monad.Trans.Random.Strict.RandT g m)
instance (GHC.Base.Monad m, System.Random.Internal.RandomGen g) => System.Random.Stateful.RandomGenM (Control.Monad.Trans.Random.Strict.RandGen g) g (Control.Monad.Trans.Random.Strict.RandT g m)
instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (Control.Monad.Trans.Random.Strict.RandT g m)
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Control.Monad.Trans.Random.Strict.RandT g m)
instance (Control.Monad.Reader.Class.MonadReader r m, Control.Monad.Writer.Class.MonadWriter w m, Control.Monad.State.Class.MonadState s m) => Control.Monad.RWS.Class.MonadRWS r w s (Control.Monad.Trans.Random.Strict.RandT g m)
instance (System.Random.Internal.RandomGen g, GHC.Base.Monad m) => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.Random.Strict.RandT g m)
instance (System.Random.Internal.RandomGen g, GHC.Base.Monad m) => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.Random.Strict.RandT g m)
instance (GHC.Base.Monad m, System.Random.Internal.RandomGen g) => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.Random.Strict.RandT g m)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Control.Monad.Trans.Random.Strict.RandT g m)
instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Control.Monad.Trans.Random.Strict.RandT s m)
instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Control.Monad.Trans.Random.Strict.RandT g m)


-- | Lazy random monads, passing a random number generator through a
--   computation. See below for examples.
--   
--   For a strict version with the same interface, see
--   <a>Control.Monad.Trans.Random.Strict</a>.
module Control.Monad.Trans.Random.Lazy

-- | A random monad parameterized by the type <tt>g</tt> of the generator
--   to carry.
--   
--   The <a>return</a> function leaves the generator unchanged, while
--   <a>&gt;&gt;=</a> uses the final generator of the first computation as
--   the initial generator of the second.
type Rand g = RandT g Identity

-- | Construct a random monad computation from a function. (The inverse of
--   <a>runRand</a>.)
liftRand :: (g -> (a, g)) -> Rand g a

-- | Unwrap a random monad computation as a function. (The inverse of
--   <a>liftRand</a>.)
runRand :: Rand g a -> g -> (a, g)

-- | Evaluate a random computation with the given initial generator and
--   return the final value, discarding the final generator.
--   
--   <ul>
--   <li><pre><a>evalRand</a> m s = fst (<a>runRand</a> m s)</pre></li>
--   </ul>
evalRand :: Rand g a -> g -> a

-- | Evaluate a random computation with the given initial generator and
--   return the final generator, discarding the final value.
--   
--   <ul>
--   <li><pre><a>execRand</a> m s = snd (<a>runRand</a> m s)</pre></li>
--   </ul>
execRand :: Rand g a -> g -> g

-- | Map both the return value and final generator of a computation using
--   the given function.
--   
--   <ul>
--   <li><pre><a>runRand</a> (<a>mapRand</a> f m) = f . <a>runRand</a>
--   m</pre></li>
--   </ul>
mapRand :: ((a, g) -> (b, g)) -> Rand g a -> Rand g b

-- | <tt><a>withRand</a> f m</tt> executes action <tt>m</tt> on a generator
--   modified by applying <tt>f</tt>.
--   
--   <ul>
--   <li><pre><a>withRand</a> f m = <a>modify</a> f &gt;&gt; m</pre></li>
--   </ul>
withRand :: (g -> g) -> Rand g a -> Rand g a

-- | Evaluate a random computation in the <a>IO</a> monad, splitting the
--   global standard generator to get a new one for the computation.
evalRandIO :: Rand StdGen a -> IO a

-- | A random transformer monad parameterized by:
--   
--   <ul>
--   <li><tt>g</tt> - The generator.</li>
--   <li><tt>m</tt> - The inner monad.</li>
--   </ul>
--   
--   The <a>return</a> function leaves the generator unchanged, while
--   <a>&gt;&gt;=</a> uses the final generator of the first computation as
--   the initial generator of the second.
data RandT g m a

-- | Construct a random monad computation from an impure function. (The
--   inverse of <a>runRandT</a>.)
liftRandT :: (g -> m (a, g)) -> RandT g m a

-- | Unwrap a random monad computation as an impure function. (The inverse
--   of <a>liftRandT</a>.)
runRandT :: RandT g m a -> g -> m (a, g)

-- | Evaluate a random computation with the given initial generator and
--   return the final value, discarding the final generator.
--   
--   <ul>
--   <li><pre><a>evalRandT</a> m g = liftM fst (<a>runRandT</a> m
--   g)</pre></li>
--   </ul>
evalRandT :: Monad m => RandT g m a -> g -> m a

-- | Evaluate a random computation with the given initial generator and
--   return the final generator, discarding the final value.
--   
--   <ul>
--   <li><pre><a>execRandT</a> m g = liftM snd (<a>runRandT</a> m
--   g)</pre></li>
--   </ul>
execRandT :: Monad m => RandT g m a -> g -> m g

-- | Map both the return value and final generator of a computation using
--   the given function.
--   
--   <ul>
--   <li><pre><a>runRandT</a> (<a>mapRandT</a> f m) = f . <a>runRandT</a>
--   m</pre></li>
--   </ul>
mapRandT :: (m (a, g) -> n (b, g)) -> RandT g m a -> RandT g n b

-- | <tt><a>withRandT</a> f m</tt> executes action <tt>m</tt> on a
--   generator modified by applying <tt>f</tt>.
--   
--   <ul>
--   <li><pre><a>withRandT</a> f m = <a>modify</a> f &gt;&gt; m</pre></li>
--   </ul>
withRandT :: (g -> g) -> RandT g m a -> RandT g m a

-- | Uniform lifting of a <tt>callCC</tt> operation to the new monad. This
--   version rolls back to the original state on entering the continuation.
liftCallCC :: CallCC m (a, g) (b, g) -> CallCC (RandT g m) a b

-- | In-situ lifting of a <tt>callCC</tt> operation to the new monad. This
--   version uses the current state on entering the continuation. It does
--   not satisfy the uniformity property (see
--   <a>Control.Monad.Signatures</a>).
liftCallCC' :: CallCC m (a, g) (b, g) -> CallCC (RandT g m) a b

-- | Lift a <tt>catchE</tt> operation to the new monad.
liftCatch :: Catch e m (a, g) -> Catch e (RandT g m) a

-- | Lift a <tt>listen</tt> operation to the new monad.
liftListen :: Monad m => Listen w m (a, g) -> Listen w (RandT g m) a

-- | Lift a <tt>pass</tt> operation to the new monad.
liftPass :: Monad m => Pass w m (a, g) -> Pass w (RandT g m) a

-- | Evaluate a random computation that is embedded in the <a>IO</a> monad,
--   splitting the global standard generator to get a new one for the
--   computation.
evalRandTIO :: MonadIO m => RandT StdGen m a -> m a

-- | A proxy that carries information about the type of generator to use
--   with <tt>RandT</tt> monad and its <a>StatefulGen</a> instance.
data RandGen g
RandGen :: RandGen g

-- | A <a>RandT</a> runner that allows using it with <a>StatefulGen</a>
--   restricted actions. Returns the outcome of random computation and the
--   new pseudo-random-number generator
--   
--   <pre>
--   &gt;&gt;&gt; withRandGen (mkStdGen 2021) uniformM :: IO (Int, StdGen)
--   (6070831465987696718,StdGen {unStdGen = SMGen 4687568268719557181 4805600293067301895})
--   </pre>
withRandGen :: g -> (RandGen g -> RandT g m a) -> m (a, g)

-- | Same as <a>withRandGen</a>, but discards the resulting generator.
--   
--   <pre>
--   &gt;&gt;&gt; withRandGen_ (mkStdGen 2021) uniformM :: IO Int
--   6070831465987696718
--   </pre>
withRandGen_ :: Monad m => g -> (RandGen g -> RandT g m a) -> m a
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Control.Monad.Trans.Random.Lazy.RandT g m)
instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Control.Monad.Trans.Random.Lazy.RandT g m)
instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Control.Monad.Trans.Random.Lazy.RandT g m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Monad.Trans.Random.Lazy.RandT g m)
instance Control.Monad.Trans.Class.MonadTrans (Control.Monad.Trans.Random.Lazy.RandT g)
instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Control.Monad.Trans.Random.Lazy.RandT g m)
instance GHC.Base.Monad m => GHC.Base.Monad (Control.Monad.Trans.Random.Lazy.RandT g m)
instance GHC.Base.MonadPlus m => GHC.Base.Alternative (Control.Monad.Trans.Random.Lazy.RandT g m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Control.Monad.Trans.Random.Lazy.RandT g m)
instance GHC.Base.Functor m => GHC.Base.Functor (Control.Monad.Trans.Random.Lazy.RandT g m)
instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (Control.Monad.Trans.Random.Lazy.RandT g m)
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Control.Monad.Trans.Random.Lazy.RandT g m)
instance (Control.Monad.Reader.Class.MonadReader r m, Control.Monad.Writer.Class.MonadWriter w m, Control.Monad.State.Class.MonadState s m) => Control.Monad.RWS.Class.MonadRWS r w s (Control.Monad.Trans.Random.Lazy.RandT g m)
instance (System.Random.Internal.RandomGen g, GHC.Base.Monad m) => Control.Monad.Random.Class.MonadRandom (Control.Monad.Trans.Random.Lazy.RandT g m)
instance (System.Random.Internal.RandomGen g, GHC.Base.Monad m) => Control.Monad.Random.Class.MonadSplit g (Control.Monad.Trans.Random.Lazy.RandT g m)
instance (GHC.Base.Monad m, System.Random.Internal.RandomGen g) => Control.Monad.Random.Class.MonadInterleave (Control.Monad.Trans.Random.Lazy.RandT g m)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Control.Monad.Trans.Random.Lazy.RandT g m)
instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Control.Monad.Trans.Random.Lazy.RandT s m)
instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Control.Monad.Trans.Random.Lazy.RandT g m)
instance (GHC.Base.Monad m, System.Random.Internal.RandomGen g) => System.Random.Internal.StatefulGen (Control.Monad.Trans.Random.Strict.RandGen g) (Control.Monad.Trans.Random.Lazy.RandT g m)
instance (GHC.Base.Monad m, System.Random.Internal.RandomGen g) => System.Random.Stateful.RandomGenM (Control.Monad.Trans.Random.Strict.RandGen g) g (Control.Monad.Trans.Random.Lazy.RandT g m)


-- | Random monads, passing a random number generator through a
--   computation.
--   
--   This version is lazy; for a strict version, see
--   <a>Control.Monad.Trans.Random.Strict</a>, which has the same
--   interface.
module Control.Monad.Trans.Random


-- | Random monads that are lazy in the generator state. For a strict
--   version, see <a>Control.Monad.Random.Strict</a>, which has the same
--   interface.
module Control.Monad.Random.Lazy

-- | A random monad parameterized by the type <tt>g</tt> of the generator
--   to carry.
--   
--   The <a>return</a> function leaves the generator unchanged, while
--   <a>&gt;&gt;=</a> uses the final generator of the first computation as
--   the initial generator of the second.
type Rand g = RandT g Identity

-- | Construct a random monad computation from a function. (The inverse of
--   <a>runRand</a>.)
liftRand :: (g -> (a, g)) -> Rand g a

-- | Unwrap a random monad computation as a function. (The inverse of
--   <a>liftRand</a>.)
runRand :: Rand g a -> g -> (a, g)

-- | Evaluate a random computation with the given initial generator and
--   return the final value, discarding the final generator.
--   
--   <ul>
--   <li><pre><a>evalRand</a> m s = fst (<a>runRand</a> m s)</pre></li>
--   </ul>
evalRand :: Rand g a -> g -> a

-- | Evaluate a random computation with the given initial generator and
--   return the final generator, discarding the final value.
--   
--   <ul>
--   <li><pre><a>execRand</a> m s = snd (<a>runRand</a> m s)</pre></li>
--   </ul>
execRand :: Rand g a -> g -> g

-- | Map both the return value and final generator of a computation using
--   the given function.
--   
--   <ul>
--   <li><pre><a>runRand</a> (<a>mapRand</a> f m) = f . <a>runRand</a>
--   m</pre></li>
--   </ul>
mapRand :: ((a, g) -> (b, g)) -> Rand g a -> Rand g b

-- | <tt><a>withRand</a> f m</tt> executes action <tt>m</tt> on a generator
--   modified by applying <tt>f</tt>.
--   
--   <ul>
--   <li><pre><a>withRand</a> f m = <a>modify</a> f &gt;&gt; m</pre></li>
--   </ul>
withRand :: (g -> g) -> Rand g a -> Rand g a

-- | Evaluate a random computation in the <a>IO</a> monad, splitting the
--   global standard generator to get a new one for the computation.
evalRandIO :: Rand StdGen a -> IO a

-- | A random transformer monad parameterized by:
--   
--   <ul>
--   <li><tt>g</tt> - The generator.</li>
--   <li><tt>m</tt> - The inner monad.</li>
--   </ul>
--   
--   The <a>return</a> function leaves the generator unchanged, while
--   <a>&gt;&gt;=</a> uses the final generator of the first computation as
--   the initial generator of the second.
data RandT g m a

-- | Construct a random monad computation from an impure function. (The
--   inverse of <a>runRandT</a>.)
liftRandT :: (g -> m (a, g)) -> RandT g m a

-- | Unwrap a random monad computation as an impure function. (The inverse
--   of <a>liftRandT</a>.)
runRandT :: RandT g m a -> g -> m (a, g)

-- | Evaluate a random computation with the given initial generator and
--   return the final value, discarding the final generator.
--   
--   <ul>
--   <li><pre><a>evalRandT</a> m g = liftM fst (<a>runRandT</a> m
--   g)</pre></li>
--   </ul>
evalRandT :: Monad m => RandT g m a -> g -> m a

-- | Evaluate a random computation with the given initial generator and
--   return the final generator, discarding the final value.
--   
--   <ul>
--   <li><pre><a>execRandT</a> m g = liftM snd (<a>runRandT</a> m
--   g)</pre></li>
--   </ul>
execRandT :: Monad m => RandT g m a -> g -> m g

-- | Map both the return value and final generator of a computation using
--   the given function.
--   
--   <ul>
--   <li><pre><a>runRandT</a> (<a>mapRandT</a> f m) = f . <a>runRandT</a>
--   m</pre></li>
--   </ul>
mapRandT :: (m (a, g) -> n (b, g)) -> RandT g m a -> RandT g n b

-- | <tt><a>withRandT</a> f m</tt> executes action <tt>m</tt> on a
--   generator modified by applying <tt>f</tt>.
--   
--   <ul>
--   <li><pre><a>withRandT</a> f m = <a>modify</a> f &gt;&gt; m</pre></li>
--   </ul>
withRandT :: (g -> g) -> RandT g m a -> RandT g m a

-- | Evaluate a random computation that is embedded in the <a>IO</a> monad,
--   splitting the global standard generator to get a new one for the
--   computation.
evalRandTIO :: MonadIO m => RandT StdGen m a -> m a

-- | A variant of <a>randomM</a> that uses the global pseudo-random number
--   generator <a>globalStdGen</a>.
--   
--   <pre>
--   &gt;&gt;&gt; import Data.Int
--   
--   &gt;&gt;&gt; randomIO :: IO Int32
--   -1580093805
--   </pre>
--   
--   This function is equivalent to <tt><a>getStdRandom</a>
--   <a>random</a></tt> and is included in this interface for historical
--   reasons and backwards compatibility. It is recommended to use
--   <a>uniformM</a> instead, possibly with the <a>globalStdGen</a> if
--   relying on the global state is acceptable.
--   
--   <pre>
--   &gt;&gt;&gt; import System.Random.Stateful
--   
--   &gt;&gt;&gt; uniformM globalStdGen :: IO Int32
--   -1649127057
--   </pre>
randomIO :: (Random a, MonadIO m) => m a

-- | A variant of <a>randomRM</a> that uses the global pseudo-random number
--   generator <a>globalStdGen</a>
--   
--   <pre>
--   &gt;&gt;&gt; randomRIO (2020, 2100) :: IO Int
--   2040
--   </pre>
--   
--   Similar to <a>randomIO</a>, this function is equivalent to
--   <tt><a>getStdRandom</a> <a>randomR</a></tt> and is included in this
--   interface for historical reasons and backwards compatibility. It is
--   recommended to use <a>uniformRM</a> instead, possibly with the
--   <a>globalStdGen</a> if relying on the global state is acceptable.
--   
--   <pre>
--   &gt;&gt;&gt; import System.Random.Stateful
--   
--   &gt;&gt;&gt; uniformRM (2020, 2100) globalStdGen :: IO Int
--   2079
--   </pre>
randomRIO :: (Random a, MonadIO m) => (a, a) -> m a

-- | Uses the supplied function to get a value from the current global
--   random generator, and updates the global generator with the new
--   generator returned by the function. For example, <tt>rollDice</tt>
--   produces a pseudo-random integer between 1 and 6:
--   
--   <pre>
--   &gt;&gt;&gt; rollDice = getStdRandom (randomR (1, 6))
--   
--   &gt;&gt;&gt; replicateM 10 (rollDice :: IO Int)
--   [5,6,6,1,1,6,4,2,4,1]
--   </pre>
--   
--   This is an outdated function and it is recommended to switch to its
--   equivalent <a>applyAtomicGen</a> instead, possibly with the
--   <a>globalStdGen</a> if relying on the global state is acceptable.
--   
--   <pre>
--   &gt;&gt;&gt; import System.Random.Stateful
--   
--   &gt;&gt;&gt; rollDice = applyAtomicGen (uniformR (1, 6)) globalStdGen
--   
--   &gt;&gt;&gt; replicateM 10 (rollDice :: IO Int)
--   [4,6,1,1,4,4,3,2,1,2]
--   </pre>
getStdRandom :: MonadIO m => (StdGen -> (a, StdGen)) -> m a

-- | Applies <a>split</a> to the current global pseudo-random generator
--   <a>globalStdGen</a>, updates it with one of the results, and returns
--   the other.
newStdGen :: MonadIO m => m StdGen

-- | Gets the global pseudo-random number generator. Extracts the contents
--   of <a>globalStdGen</a>
getStdGen :: MonadIO m => m StdGen

-- | Sets the global pseudo-random number generator. Overwrites the
--   contents of <a>globalStdGen</a>
setStdGen :: MonadIO m => StdGen -> m ()

-- | Initialize <a>StdGen</a> using system entropy (i.e.
--   <tt>/dev/urandom</tt>) when it is available, while falling back on
--   using system time as the seed.
initStdGen :: MonadIO m => m StdGen

-- | Generates a <a>ByteString</a> of the specified size using a pure
--   pseudo-random number generator. See <a>uniformByteStringM</a> for the
--   monadic version.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; import System.Random
--   
--   &gt;&gt;&gt; import Data.ByteString
--   
--   &gt;&gt;&gt; let pureGen = mkStdGen 137
--   
--   &gt;&gt;&gt; unpack . fst . genByteString 10 $ pureGen
--   [51,123,251,37,49,167,90,109,1,4]
--   </pre>
genByteString :: RandomGen g => Int -> g -> (ByteString, g)

-- | The class of types for which random values can be generated. Most
--   instances of <a>Random</a> will produce values that are uniformly
--   distributed on the full range, but for those types without a
--   well-defined "full range" some sensible default subrange will be
--   selected.
--   
--   <a>Random</a> exists primarily for backwards compatibility with
--   version 1.1 of this library. In new code, use the better specified
--   <a>Uniform</a> and <a>UniformRange</a> instead.
class Random a

-- | Takes a range <i>(lo,hi)</i> and a pseudo-random number generator
--   <i>g</i>, and returns a pseudo-random value uniformly distributed over
--   the closed interval <i>[lo,hi]</i>, together with a new generator. It
--   is unspecified what happens if <i>lo&gt;hi</i>, but usually the values
--   will simply get swapped.
--   
--   <pre>
--   &gt;&gt;&gt; let gen = mkStdGen 2021
--   
--   &gt;&gt;&gt; fst $ randomR ('a', 'z') gen
--   't'
--   
--   &gt;&gt;&gt; fst $ randomR ('z', 'a') gen
--   't'
--   </pre>
--   
--   For continuous types there is no requirement that the values <i>lo</i>
--   and <i>hi</i> are ever produced, but they may be, depending on the
--   implementation and the interval.
--   
--   There is no requirement to follow the <tt>Ord</tt> instance and the
--   concept of range can be defined on per type basis. For example product
--   types will treat their values independently:
--   
--   <pre>
--   &gt;&gt;&gt; fst $ randomR (('a', 5.0), ('z', 10.0)) $ mkStdGen 2021
--   ('t',6.240232662366563)
--   </pre>
--   
--   In case when a lawful range is desired <a>uniformR</a> should be used
--   instead.
randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g)

-- | The same as <a>randomR</a>, but using a default range determined by
--   the type:
--   
--   <ul>
--   <li>For bounded types (instances of <a>Bounded</a>, such as
--   <a>Char</a>), the range is normally the whole type.</li>
--   <li>For floating point types, the range is normally the closed
--   interval <tt>[0,1]</tt>.</li>
--   <li>For <a>Integer</a>, the range is (arbitrarily) the range of
--   <a>Int</a>.</li>
--   </ul>
random :: (Random a, RandomGen g) => g -> (a, g)

-- | Plural variant of <a>randomR</a>, producing an infinite list of
--   pseudo-random values instead of returning a new generator.
randomRs :: (Random a, RandomGen g) => (a, a) -> g -> [a]

-- | Plural variant of <a>random</a>, producing an infinite list of
--   pseudo-random values instead of returning a new generator.
randoms :: (Random a, RandomGen g) => g -> [a]

-- | Constructs a <a>StdGen</a> deterministically.
mkStdGen :: Int -> StdGen

-- | <a>RandomGen</a> is an interface to pure pseudo-random number
--   generators.
--   
--   <a>StdGen</a> is the standard <a>RandomGen</a> instance provided by
--   this library.
class RandomGen g

-- | Returns an <a>Int</a> that is uniformly distributed over the range
--   returned by <a>genRange</a> (including both end points), and a new
--   generator. Using <a>next</a> is inefficient as all operations go via
--   <a>Integer</a>. See <a>here</a> for more details. It is thus
--   deprecated.
next :: RandomGen g => g -> (Int, g)

-- | Returns a <a>Word8</a> that is uniformly distributed over the entire
--   <a>Word8</a> range.
genWord8 :: RandomGen g => g -> (Word8, g)

-- | Returns a <a>Word16</a> that is uniformly distributed over the entire
--   <a>Word16</a> range.
genWord16 :: RandomGen g => g -> (Word16, g)

-- | Returns a <a>Word32</a> that is uniformly distributed over the entire
--   <a>Word32</a> range.
genWord32 :: RandomGen g => g -> (Word32, g)

-- | Returns a <a>Word64</a> that is uniformly distributed over the entire
--   <a>Word64</a> range.
genWord64 :: RandomGen g => g -> (Word64, g)

-- | <tt>genWord32R upperBound g</tt> returns a <a>Word32</a> that is
--   uniformly distributed over the range <tt>[0, upperBound]</tt>.
genWord32R :: RandomGen g => Word32 -> g -> (Word32, g)

-- | <tt>genWord64R upperBound g</tt> returns a <a>Word64</a> that is
--   uniformly distributed over the range <tt>[0, upperBound]</tt>.
genWord64R :: RandomGen g => Word64 -> g -> (Word64, g)

-- | <tt>genShortByteString n g</tt> returns a <a>ShortByteString</a> of
--   length <tt>n</tt> filled with pseudo-random bytes.
genShortByteString :: RandomGen g => Int -> g -> (ShortByteString, g)

-- | Yields the range of values returned by <a>next</a>.
--   
--   It is required that:
--   
--   <ul>
--   <li>If <tt>(a, b) = <a>genRange</a> g</tt>, then <tt>a &lt;
--   b</tt>.</li>
--   <li><a>genRange</a> must not examine its argument so the value it
--   returns is determined only by the instance of <a>RandomGen</a>.</li>
--   </ul>
--   
--   The default definition spans the full range of <a>Int</a>.
genRange :: RandomGen g => g -> (Int, Int)

-- | Returns two distinct pseudo-random number generators.
--   
--   Implementations should take care to ensure that the resulting
--   generators are not correlated. Some pseudo-random number generators
--   are not splittable. In that case, the <a>split</a> implementation
--   should fail with a descriptive <a>error</a> message.
split :: RandomGen g => g -> (g, g)

-- | The standard pseudo-random number generator.
data StdGen

-- | The class of types for which a uniformly distributed value can be
--   drawn from all possible values of the type.
class Uniform a

-- | The class of types for which a uniformly distributed value can be
--   drawn from a range.
class UniformRange a

-- | A type class for data with a finite number of inhabitants. This type
--   class is used in default implementations of <a>Uniform</a>.
--   
--   Users are not supposed to write instances of <a>Finite</a> manually.
--   There is a default implementation in terms of <a>Generic</a> instead.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XDeriveGeneric -XDeriveAnyClass
--   
--   &gt;&gt;&gt; import GHC.Generics (Generic)
--   
--   &gt;&gt;&gt; data MyBool = MyTrue | MyFalse deriving (Generic, Finite)
--   
--   &gt;&gt;&gt; data Action = Code MyBool | Eat (Maybe Bool) | Sleep deriving (Generic, Finite)
--   </pre>
class Finite a


-- | This module is provided for backwards compatibility, and simply
--   re-exports <a>Control.Monad.Random.Lazy</a>.
module Control.Monad.Random


-- | Random monads that are strict in the generator state. For a lazy
--   version, see <a>Control.Monad.Random.Lazy</a>, which has the same
--   interface.
module Control.Monad.Random.Strict

-- | A random monad parameterized by the type <tt>g</tt> of the generator
--   to carry.
--   
--   The <a>return</a> function leaves the generator unchanged, while
--   <a>&gt;&gt;=</a> uses the final generator of the first computation as
--   the initial generator of the second.
type Rand g = RandT g Identity

-- | Construct a random monad computation from a function. (The inverse of
--   <a>runRand</a>.)
liftRand :: (g -> (a, g)) -> Rand g a

-- | Unwrap a random monad computation as a function. (The inverse of
--   <a>liftRand</a>.)
runRand :: Rand g a -> g -> (a, g)

-- | Evaluate a random computation with the given initial generator and
--   return the final value, discarding the final generator.
--   
--   <ul>
--   <li><pre><a>evalRand</a> m s = fst (<a>runRand</a> m s)</pre></li>
--   </ul>
evalRand :: Rand g a -> g -> a

-- | Evaluate a random computation with the given initial generator and
--   return the final generator, discarding the final value.
--   
--   <ul>
--   <li><pre><a>execRand</a> m s = snd (<a>runRand</a> m s)</pre></li>
--   </ul>
execRand :: Rand g a -> g -> g

-- | Map both the return value and final generator of a computation using
--   the given function.
--   
--   <ul>
--   <li><pre><a>runRand</a> (<a>mapRand</a> f m) = f . <a>runRand</a>
--   m</pre></li>
--   </ul>
mapRand :: ((a, g) -> (b, g)) -> Rand g a -> Rand g b

-- | <tt><a>withRand</a> f m</tt> executes action <tt>m</tt> on a generator
--   modified by applying <tt>f</tt>.
--   
--   <ul>
--   <li><pre><a>withRand</a> f m = <a>modify</a> f &gt;&gt; m</pre></li>
--   </ul>
withRand :: (g -> g) -> Rand g a -> Rand g a

-- | Evaluate a random computation in the <a>IO</a> monad, splitting the
--   global standard generator to get a new one for the computation.
evalRandIO :: Rand StdGen a -> IO a

-- | A random transformer monad parameterized by:
--   
--   <ul>
--   <li><tt>g</tt> - The generator.</li>
--   <li><tt>m</tt> - The inner monad.</li>
--   </ul>
--   
--   The <a>return</a> function leaves the generator unchanged, while
--   <a>&gt;&gt;=</a> uses the final generator of the first computation as
--   the initial generator of the second.
data RandT g m a

-- | Construct a random monad computation from an impure function. (The
--   inverse of <a>runRandT</a>.)
liftRandT :: (g -> m (a, g)) -> RandT g m a

-- | Unwrap a random monad computation as an impure function. (The inverse
--   of <a>liftRandT</a>.)
runRandT :: RandT g m a -> g -> m (a, g)

-- | Evaluate a random computation with the given initial generator and
--   return the final value, discarding the final generator.
--   
--   <ul>
--   <li><pre><a>evalRandT</a> m g = liftM fst (<a>runRandT</a> m
--   g)</pre></li>
--   </ul>
evalRandT :: Monad m => RandT g m a -> g -> m a

-- | Evaluate a random computation with the given initial generator and
--   return the final generator, discarding the final value.
--   
--   <ul>
--   <li><pre><a>execRandT</a> m g = liftM snd (<a>runRandT</a> m
--   g)</pre></li>
--   </ul>
execRandT :: Monad m => RandT g m a -> g -> m g

-- | Map both the return value and final generator of a computation using
--   the given function.
--   
--   <ul>
--   <li><pre><a>runRandT</a> (<a>mapRandT</a> f m) = f . <a>runRandT</a>
--   m</pre></li>
--   </ul>
mapRandT :: (m (a, g) -> n (b, g)) -> RandT g m a -> RandT g n b

-- | <tt><a>withRandT</a> f m</tt> executes action <tt>m</tt> on a
--   generator modified by applying <tt>f</tt>.
--   
--   <ul>
--   <li><pre><a>withRandT</a> f m = <a>modify</a> f &gt;&gt; m</pre></li>
--   </ul>
withRandT :: (g -> g) -> RandT g m a -> RandT g m a

-- | Evaluate a random computation that is embedded in the <a>IO</a> monad,
--   splitting the global standard generator to get a new one for the
--   computation.
evalRandTIO :: MonadIO m => RandT StdGen m a -> m a

-- | A variant of <a>randomM</a> that uses the global pseudo-random number
--   generator <a>globalStdGen</a>.
--   
--   <pre>
--   &gt;&gt;&gt; import Data.Int
--   
--   &gt;&gt;&gt; randomIO :: IO Int32
--   -1580093805
--   </pre>
--   
--   This function is equivalent to <tt><a>getStdRandom</a>
--   <a>random</a></tt> and is included in this interface for historical
--   reasons and backwards compatibility. It is recommended to use
--   <a>uniformM</a> instead, possibly with the <a>globalStdGen</a> if
--   relying on the global state is acceptable.
--   
--   <pre>
--   &gt;&gt;&gt; import System.Random.Stateful
--   
--   &gt;&gt;&gt; uniformM globalStdGen :: IO Int32
--   -1649127057
--   </pre>
randomIO :: (Random a, MonadIO m) => m a

-- | A variant of <a>randomRM</a> that uses the global pseudo-random number
--   generator <a>globalStdGen</a>
--   
--   <pre>
--   &gt;&gt;&gt; randomRIO (2020, 2100) :: IO Int
--   2040
--   </pre>
--   
--   Similar to <a>randomIO</a>, this function is equivalent to
--   <tt><a>getStdRandom</a> <a>randomR</a></tt> and is included in this
--   interface for historical reasons and backwards compatibility. It is
--   recommended to use <a>uniformRM</a> instead, possibly with the
--   <a>globalStdGen</a> if relying on the global state is acceptable.
--   
--   <pre>
--   &gt;&gt;&gt; import System.Random.Stateful
--   
--   &gt;&gt;&gt; uniformRM (2020, 2100) globalStdGen :: IO Int
--   2079
--   </pre>
randomRIO :: (Random a, MonadIO m) => (a, a) -> m a

-- | Uses the supplied function to get a value from the current global
--   random generator, and updates the global generator with the new
--   generator returned by the function. For example, <tt>rollDice</tt>
--   produces a pseudo-random integer between 1 and 6:
--   
--   <pre>
--   &gt;&gt;&gt; rollDice = getStdRandom (randomR (1, 6))
--   
--   &gt;&gt;&gt; replicateM 10 (rollDice :: IO Int)
--   [5,6,6,1,1,6,4,2,4,1]
--   </pre>
--   
--   This is an outdated function and it is recommended to switch to its
--   equivalent <a>applyAtomicGen</a> instead, possibly with the
--   <a>globalStdGen</a> if relying on the global state is acceptable.
--   
--   <pre>
--   &gt;&gt;&gt; import System.Random.Stateful
--   
--   &gt;&gt;&gt; rollDice = applyAtomicGen (uniformR (1, 6)) globalStdGen
--   
--   &gt;&gt;&gt; replicateM 10 (rollDice :: IO Int)
--   [4,6,1,1,4,4,3,2,1,2]
--   </pre>
getStdRandom :: MonadIO m => (StdGen -> (a, StdGen)) -> m a

-- | Applies <a>split</a> to the current global pseudo-random generator
--   <a>globalStdGen</a>, updates it with one of the results, and returns
--   the other.
newStdGen :: MonadIO m => m StdGen

-- | Gets the global pseudo-random number generator. Extracts the contents
--   of <a>globalStdGen</a>
getStdGen :: MonadIO m => m StdGen

-- | Sets the global pseudo-random number generator. Overwrites the
--   contents of <a>globalStdGen</a>
setStdGen :: MonadIO m => StdGen -> m ()

-- | Initialize <a>StdGen</a> using system entropy (i.e.
--   <tt>/dev/urandom</tt>) when it is available, while falling back on
--   using system time as the seed.
initStdGen :: MonadIO m => m StdGen

-- | Generates a <a>ByteString</a> of the specified size using a pure
--   pseudo-random number generator. See <a>uniformByteStringM</a> for the
--   monadic version.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; import System.Random
--   
--   &gt;&gt;&gt; import Data.ByteString
--   
--   &gt;&gt;&gt; let pureGen = mkStdGen 137
--   
--   &gt;&gt;&gt; unpack . fst . genByteString 10 $ pureGen
--   [51,123,251,37,49,167,90,109,1,4]
--   </pre>
genByteString :: RandomGen g => Int -> g -> (ByteString, g)

-- | The class of types for which random values can be generated. Most
--   instances of <a>Random</a> will produce values that are uniformly
--   distributed on the full range, but for those types without a
--   well-defined "full range" some sensible default subrange will be
--   selected.
--   
--   <a>Random</a> exists primarily for backwards compatibility with
--   version 1.1 of this library. In new code, use the better specified
--   <a>Uniform</a> and <a>UniformRange</a> instead.
class Random a

-- | Takes a range <i>(lo,hi)</i> and a pseudo-random number generator
--   <i>g</i>, and returns a pseudo-random value uniformly distributed over
--   the closed interval <i>[lo,hi]</i>, together with a new generator. It
--   is unspecified what happens if <i>lo&gt;hi</i>, but usually the values
--   will simply get swapped.
--   
--   <pre>
--   &gt;&gt;&gt; let gen = mkStdGen 2021
--   
--   &gt;&gt;&gt; fst $ randomR ('a', 'z') gen
--   't'
--   
--   &gt;&gt;&gt; fst $ randomR ('z', 'a') gen
--   't'
--   </pre>
--   
--   For continuous types there is no requirement that the values <i>lo</i>
--   and <i>hi</i> are ever produced, but they may be, depending on the
--   implementation and the interval.
--   
--   There is no requirement to follow the <tt>Ord</tt> instance and the
--   concept of range can be defined on per type basis. For example product
--   types will treat their values independently:
--   
--   <pre>
--   &gt;&gt;&gt; fst $ randomR (('a', 5.0), ('z', 10.0)) $ mkStdGen 2021
--   ('t',6.240232662366563)
--   </pre>
--   
--   In case when a lawful range is desired <a>uniformR</a> should be used
--   instead.
randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g)

-- | The same as <a>randomR</a>, but using a default range determined by
--   the type:
--   
--   <ul>
--   <li>For bounded types (instances of <a>Bounded</a>, such as
--   <a>Char</a>), the range is normally the whole type.</li>
--   <li>For floating point types, the range is normally the closed
--   interval <tt>[0,1]</tt>.</li>
--   <li>For <a>Integer</a>, the range is (arbitrarily) the range of
--   <a>Int</a>.</li>
--   </ul>
random :: (Random a, RandomGen g) => g -> (a, g)

-- | Plural variant of <a>randomR</a>, producing an infinite list of
--   pseudo-random values instead of returning a new generator.
randomRs :: (Random a, RandomGen g) => (a, a) -> g -> [a]

-- | Plural variant of <a>random</a>, producing an infinite list of
--   pseudo-random values instead of returning a new generator.
randoms :: (Random a, RandomGen g) => g -> [a]

-- | Constructs a <a>StdGen</a> deterministically.
mkStdGen :: Int -> StdGen

-- | <a>RandomGen</a> is an interface to pure pseudo-random number
--   generators.
--   
--   <a>StdGen</a> is the standard <a>RandomGen</a> instance provided by
--   this library.
class RandomGen g

-- | Returns an <a>Int</a> that is uniformly distributed over the range
--   returned by <a>genRange</a> (including both end points), and a new
--   generator. Using <a>next</a> is inefficient as all operations go via
--   <a>Integer</a>. See <a>here</a> for more details. It is thus
--   deprecated.
next :: RandomGen g => g -> (Int, g)

-- | Returns a <a>Word8</a> that is uniformly distributed over the entire
--   <a>Word8</a> range.
genWord8 :: RandomGen g => g -> (Word8, g)

-- | Returns a <a>Word16</a> that is uniformly distributed over the entire
--   <a>Word16</a> range.
genWord16 :: RandomGen g => g -> (Word16, g)

-- | Returns a <a>Word32</a> that is uniformly distributed over the entire
--   <a>Word32</a> range.
genWord32 :: RandomGen g => g -> (Word32, g)

-- | Returns a <a>Word64</a> that is uniformly distributed over the entire
--   <a>Word64</a> range.
genWord64 :: RandomGen g => g -> (Word64, g)

-- | <tt>genWord32R upperBound g</tt> returns a <a>Word32</a> that is
--   uniformly distributed over the range <tt>[0, upperBound]</tt>.
genWord32R :: RandomGen g => Word32 -> g -> (Word32, g)

-- | <tt>genWord64R upperBound g</tt> returns a <a>Word64</a> that is
--   uniformly distributed over the range <tt>[0, upperBound]</tt>.
genWord64R :: RandomGen g => Word64 -> g -> (Word64, g)

-- | <tt>genShortByteString n g</tt> returns a <a>ShortByteString</a> of
--   length <tt>n</tt> filled with pseudo-random bytes.
genShortByteString :: RandomGen g => Int -> g -> (ShortByteString, g)

-- | Yields the range of values returned by <a>next</a>.
--   
--   It is required that:
--   
--   <ul>
--   <li>If <tt>(a, b) = <a>genRange</a> g</tt>, then <tt>a &lt;
--   b</tt>.</li>
--   <li><a>genRange</a> must not examine its argument so the value it
--   returns is determined only by the instance of <a>RandomGen</a>.</li>
--   </ul>
--   
--   The default definition spans the full range of <a>Int</a>.
genRange :: RandomGen g => g -> (Int, Int)

-- | Returns two distinct pseudo-random number generators.
--   
--   Implementations should take care to ensure that the resulting
--   generators are not correlated. Some pseudo-random number generators
--   are not splittable. In that case, the <a>split</a> implementation
--   should fail with a descriptive <a>error</a> message.
split :: RandomGen g => g -> (g, g)

-- | The standard pseudo-random number generator.
data StdGen

-- | The class of types for which a uniformly distributed value can be
--   drawn from all possible values of the type.
class Uniform a

-- | The class of types for which a uniformly distributed value can be
--   drawn from a range.
class UniformRange a

-- | A type class for data with a finite number of inhabitants. This type
--   class is used in default implementations of <a>Uniform</a>.
--   
--   Users are not supposed to write instances of <a>Finite</a> manually.
--   There is a default implementation in terms of <a>Generic</a> instead.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XDeriveGeneric -XDeriveAnyClass
--   
--   &gt;&gt;&gt; import GHC.Generics (Generic)
--   
--   &gt;&gt;&gt; data MyBool = MyTrue | MyFalse deriving (Generic, Finite)
--   
--   &gt;&gt;&gt; data Action = Code MyBool | Eat (Maybe Bool) | Sleep deriving (Generic, Finite)
--   </pre>
class Finite a
