{-# LANGUAGE CPP                        #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE Trustworthy                #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE UndecidableInstances       #-}

{- |
Module       :  Control.Monad.Trans.Random.Strict
Copyright    :  (c) Brent Yorgey 2016
License      :  BSD3 (see LICENSE)

Maintainer   :  byorgey@gmail.com
Stability    :  experimental
Portability  :  non-portable (multi-param classes, functional dependencies, undecidable instances)

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 "Control.Monad.Trans.Random.Lazy".
-}

module Control.Monad.Trans.Random.Strict
  ( -- * The Rand monad transformer
    Rand,
    liftRand,
    runRand,
    evalRand,
    execRand,
    mapRand,
    withRand,
    evalRandIO,
    -- * The RandT monad transformer
    RandT,
    liftRandT,
    runRandT,
    evalRandT,
    execRandT,
    mapRandT,
    withRandT,
    evalRandTIO,
    -- * Lifting other operations
    liftCallCC,
    liftCallCC',
    liftCatch,
    liftListen,
    liftPass,
    -- * StatefulGen interface
    RandGen(..),
    withRandGen,
    withRandGen_,
    -- * Examples
    -- ** Random monads
    -- $examples
  ) where

import Control.Applicative ( Alternative )
import Control.Arrow (first)
import Control.Monad ( liftM, MonadPlus )
import Control.Monad.Cont.Class (MonadCont(..))
import Control.Monad.Error.Class ( MonadError(..) )
import qualified Control.Monad.Fail               as Fail
import Control.Monad.Fix ( MonadFix )
import Control.Monad.IO.Class ( MonadIO(..) )
import Control.Monad.Primitive ( PrimMonad(..) )
import Control.Monad.Random.Class ( MonadInterleave(..), MonadSplit(..), MonadRandom(..) )
import Control.Monad.RWS.Class ( MonadState(..), MonadRWS, MonadReader, MonadWriter )
import Control.Monad.Signatures ( Listen, Pass, CallCC, Catch )
import Control.Monad.Trans.Class ( MonadTrans(..) )
import qualified Control.Monad.Trans.State.Strict as StrictState
import Data.Functor.Identity ( Identity(runIdentity) )
#if MIN_VERSION_random(1,2,0)
import           System.Random.Stateful
#else
import           System.Random
#endif

-- | A random monad parameterized by the type @g@ of the generator to carry.
--
-- The 'return' function leaves the generator unchanged, while '>>=' 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 'runRand'.)
liftRand
  :: (g -> (a, g))
  -- ^ pure random transformer
  -> Rand g a
  -- ^ equivalent generator-passing computation
liftRand :: forall g a. (g -> (a, g)) -> Rand g a
liftRand = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state

-- | Unwrap a random monad computation as a function.
-- (The inverse of 'liftRand'.)
runRand
  :: Rand g a
  -- ^ generator-passing computation to execute
  -> g
  -- ^ initial generator
  -> (a, g)
  -- ^ return value and final generator
runRand :: forall g a. Rand g a -> g -> (a, g)
runRand Rand g a
t = forall a. Identity a -> a
runIdentity forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall g (m :: * -> *) a. RandT g m a -> g -> m (a, g)
runRandT Rand g a
t

-- | Evaluate a random computation with the given initial generator and return
-- the final value, discarding the final generator.
--
-- * @'evalRand' m s = fst ('runRand' m s)@
evalRand
  :: Rand g a
  -- ^ generator-passing computation to execute
  -> g
  -- ^ initial generator
  -> a
  -- ^ return value of the random computation
evalRand :: forall g a. Rand g a -> g -> a
evalRand Rand g a
t = forall a. Identity a -> a
runIdentity forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) g a. Monad m => RandT g m a -> g -> m a
evalRandT Rand g a
t

-- | Evaluate a random computation with the given initial generator and return
-- the final generator, discarding the final value.
--
-- * @'execRand' m s = snd ('runRand' m s)@
execRand
  :: Rand g a
  -- ^ generator-passing computation to execute
  -> g
  -- ^ initial generator
  -> g
  -- ^ final generator
execRand :: forall g a. Rand g a -> g -> g
execRand Rand g a
t = forall a. Identity a -> a
runIdentity forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) g a. Monad m => RandT g m a -> g -> m g
execRandT Rand g a
t

-- | Map both the return value and final generator of a computation using the
-- given function.
--
-- * @'runRand' ('mapRand' f m) = f . 'runRand' m@
mapRand :: ((a, g) -> (b, g)) -> Rand g a -> Rand g b
mapRand :: forall a g b. ((a, g) -> (b, g)) -> Rand g a -> Rand g b
mapRand (a, g) -> (b, g)
f = forall (m :: * -> *) a g (n :: * -> *) b.
(m (a, g) -> n (b, g)) -> RandT g m a -> RandT g n b
mapRandT (forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (a, g) -> (b, g)
f)

-- | @'withRand' f m@ executes action @m@ on a generator modified by applying @f@.
--
-- * @'withRand' f m = 'modify' f >> m@
withRand :: (g -> g) -> Rand g a -> Rand g a
withRand :: forall g a. (g -> g) -> Rand g a -> Rand g a
withRand = forall g (m :: * -> *) a. (g -> g) -> RandT g m a -> RandT g m a
withRandT

-- | A random transformer monad parameterized by:
--
-- * @g@ - The generator.
--
-- * @m@ - The inner monad.
--
-- The 'return' function leaves the generator unchanged, while '>>=' uses the
-- final generator of the first computation as the initial generator of the
-- second.
newtype RandT g m a = RandT { forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT :: StrictState.StateT g m a }
  deriving (forall a b. a -> RandT g m b -> RandT g m a
forall a b. (a -> b) -> RandT g m a -> RandT g m b
forall g (m :: * -> *) a b.
Functor m =>
a -> RandT g m b -> RandT g m a
forall g (m :: * -> *) a b.
Functor m =>
(a -> b) -> RandT g m a -> RandT g m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> RandT g m b -> RandT g m a
$c<$ :: forall g (m :: * -> *) a b.
Functor m =>
a -> RandT g m b -> RandT g m a
fmap :: forall a b. (a -> b) -> RandT g m a -> RandT g m b
$cfmap :: forall g (m :: * -> *) a b.
Functor m =>
(a -> b) -> RandT g m a -> RandT g m b
Functor, forall a. a -> RandT g m a
forall a b. RandT g m a -> RandT g m b -> RandT g m a
forall a b. RandT g m a -> RandT g m b -> RandT g m b
forall a b. RandT g m (a -> b) -> RandT g m a -> RandT g m b
forall a b c.
(a -> b -> c) -> RandT g m a -> RandT g m b -> RandT g m c
forall {g} {m :: * -> *}. Monad m => Functor (RandT g m)
forall g (m :: * -> *) a. Monad m => a -> RandT g m a
forall g (m :: * -> *) a b.
Monad m =>
RandT g m a -> RandT g m b -> RandT g m a
forall g (m :: * -> *) a b.
Monad m =>
RandT g m a -> RandT g m b -> RandT g m b
forall g (m :: * -> *) a b.
Monad m =>
RandT g m (a -> b) -> RandT g m a -> RandT g m b
forall g (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> RandT g m a -> RandT g m b -> RandT g m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. RandT g m a -> RandT g m b -> RandT g m a
$c<* :: forall g (m :: * -> *) a b.
Monad m =>
RandT g m a -> RandT g m b -> RandT g m a
*> :: forall a b. RandT g m a -> RandT g m b -> RandT g m b
$c*> :: forall g (m :: * -> *) a b.
Monad m =>
RandT g m a -> RandT g m b -> RandT g m b
liftA2 :: forall a b c.
(a -> b -> c) -> RandT g m a -> RandT g m b -> RandT g m c
$cliftA2 :: forall g (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> RandT g m a -> RandT g m b -> RandT g m c
<*> :: forall a b. RandT g m (a -> b) -> RandT g m a -> RandT g m b
$c<*> :: forall g (m :: * -> *) a b.
Monad m =>
RandT g m (a -> b) -> RandT g m a -> RandT g m b
pure :: forall a. a -> RandT g m a
$cpure :: forall g (m :: * -> *) a. Monad m => a -> RandT g m a
Applicative, forall a. RandT g m a
forall a. RandT g m a -> RandT g m [a]
forall a. RandT g m a -> RandT g m a -> RandT g m a
forall {g} {m :: * -> *}. MonadPlus m => Applicative (RandT g m)
forall g (m :: * -> *) a. MonadPlus m => RandT g m a
forall g (m :: * -> *) a.
MonadPlus m =>
RandT g m a -> RandT g m [a]
forall g (m :: * -> *) a.
MonadPlus m =>
RandT g m a -> RandT g m a -> RandT g m a
forall (f :: * -> *).
Applicative f
-> (forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
many :: forall a. RandT g m a -> RandT g m [a]
$cmany :: forall g (m :: * -> *) a.
MonadPlus m =>
RandT g m a -> RandT g m [a]
some :: forall a. RandT g m a -> RandT g m [a]
$csome :: forall g (m :: * -> *) a.
MonadPlus m =>
RandT g m a -> RandT g m [a]
<|> :: forall a. RandT g m a -> RandT g m a -> RandT g m a
$c<|> :: forall g (m :: * -> *) a.
MonadPlus m =>
RandT g m a -> RandT g m a -> RandT g m a
empty :: forall a. RandT g m a
$cempty :: forall g (m :: * -> *) a. MonadPlus m => RandT g m a
Alternative, forall a. a -> RandT g m a
forall a b. RandT g m a -> RandT g m b -> RandT g m b
forall a b. RandT g m a -> (a -> RandT g m b) -> RandT g m b
forall g (m :: * -> *). Monad m => Applicative (RandT g m)
forall g (m :: * -> *) a. Monad m => a -> RandT g m a
forall g (m :: * -> *) a b.
Monad m =>
RandT g m a -> RandT g m b -> RandT g m b
forall g (m :: * -> *) a b.
Monad m =>
RandT g m a -> (a -> RandT g m b) -> RandT g m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> RandT g m a
$creturn :: forall g (m :: * -> *) a. Monad m => a -> RandT g m a
>> :: forall a b. RandT g m a -> RandT g m b -> RandT g m b
$c>> :: forall g (m :: * -> *) a b.
Monad m =>
RandT g m a -> RandT g m b -> RandT g m b
>>= :: forall a b. RandT g m a -> (a -> RandT g m b) -> RandT g m b
$c>>= :: forall g (m :: * -> *) a b.
Monad m =>
RandT g m a -> (a -> RandT g m b) -> RandT g m b
Monad, forall a. RandT g m a
forall a. RandT g m a -> RandT g m a -> RandT g m a
forall {g} {m :: * -> *}. MonadPlus m => Monad (RandT g m)
forall g (m :: * -> *). MonadPlus m => Alternative (RandT g m)
forall g (m :: * -> *) a. MonadPlus m => RandT g m a
forall g (m :: * -> *) a.
MonadPlus m =>
RandT g m a -> RandT g m a -> RandT g m a
forall (m :: * -> *).
Alternative m
-> Monad m
-> (forall a. m a)
-> (forall a. m a -> m a -> m a)
-> MonadPlus m
mplus :: forall a. RandT g m a -> RandT g m a -> RandT g m a
$cmplus :: forall g (m :: * -> *) a.
MonadPlus m =>
RandT g m a -> RandT g m a -> RandT g m a
mzero :: forall a. RandT g m a
$cmzero :: forall g (m :: * -> *) a. MonadPlus m => RandT g m a
MonadPlus, forall g (m :: * -> *) a. Monad m => m a -> RandT g m a
forall (m :: * -> *) a. Monad m => m a -> RandT g m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: forall (m :: * -> *) a. Monad m => m a -> RandT g m a
$clift :: forall g (m :: * -> *) a. Monad m => m a -> RandT g m a
MonadTrans, forall a. IO a -> RandT g m a
forall {g} {m :: * -> *}. MonadIO m => Monad (RandT g m)
forall g (m :: * -> *) a. MonadIO m => IO a -> RandT g m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
liftIO :: forall a. IO a -> RandT g m a
$cliftIO :: forall g (m :: * -> *) a. MonadIO m => IO a -> RandT g m a
MonadIO, forall a. (a -> RandT g m a) -> RandT g m a
forall {g} {m :: * -> *}. MonadFix m => Monad (RandT g m)
forall g (m :: * -> *) a.
MonadFix m =>
(a -> RandT g m a) -> RandT g m a
forall (m :: * -> *).
Monad m -> (forall a. (a -> m a) -> m a) -> MonadFix m
mfix :: forall a. (a -> RandT g m a) -> RandT g m a
$cmfix :: forall g (m :: * -> *) a.
MonadFix m =>
(a -> RandT g m a) -> RandT g m a
MonadFix, MonadReader r, MonadWriter w)

-- | Construct a random monad computation from an impure function.
-- (The inverse of 'runRandT'.)
liftRandT
  :: (g -> m (a, g))
  -- ^ impure random transformer
  -> RandT g m a
  -- ^ equivalent generator-passing computation
liftRandT :: forall g (m :: * -> *) a. (g -> m (a, g)) -> RandT g m a
liftRandT = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StrictState.StateT

-- | Unwrap a random monad computation as an impure function.
-- (The inverse of 'liftRandT'.)
runRandT
  :: RandT g m a
  -- ^ generator-passing computation to execute
  -> g
  -- ^ initial generator
  -> m (a, g)
  -- ^ return value and final generator
runRandT :: forall g (m :: * -> *) a. RandT g m a -> g -> m (a, g)
runRandT = forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
StrictState.runStateT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT

-- | Evaluate a random computation with the given initial generator and return
-- the final value, discarding the final generator.
--
-- * @'evalRandT' m g = liftM fst ('runRandT' m g)@
evalRandT :: (Monad m) => RandT g m a -> g -> m a
evalRandT :: forall (m :: * -> *) g a. Monad m => RandT g m a -> g -> m a
evalRandT = forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
StrictState.evalStateT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT

-- | Evaluate a random computation with the given initial generator and return
-- the final generator, discarding the final value.
--
-- * @'execRandT' m g = liftM snd ('runRandT' m g)@
execRandT :: (Monad m) => RandT g m a -> g -> m g
execRandT :: forall (m :: * -> *) g a. Monad m => RandT g m a -> g -> m g
execRandT = forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
StrictState.execStateT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT

-- | Map both the return value and final generator of a computation using the
-- given function.
--
-- * @'runRandT' ('mapRandT' f m) = f . 'runRandT' m@
mapRandT :: (m (a, g) -> n (b, g)) -> RandT g m a -> RandT g n b
mapRandT :: forall (m :: * -> *) a g (n :: * -> *) b.
(m (a, g) -> n (b, g)) -> RandT g m a -> RandT g n b
mapRandT m (a, g) -> n (b, g)
f = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a s (n :: * -> *) b.
(m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
StrictState.mapStateT m (a, g) -> n (b, g)
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT

-- | @'withRandT' f m@ executes action @m@ on a generator modified by applying @f@.
--
-- * @'withRandT' f m = 'modify' f >> m@
withRandT :: (g -> g) -> RandT g m a -> RandT g m a
withRandT :: forall g (m :: * -> *) a. (g -> g) -> RandT g m a -> RandT g m a
withRandT g -> g
f = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. (s -> s) -> StateT s m a -> StateT s m a
StrictState.withStateT g -> g
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT

instance (MonadCont m) => MonadCont (RandT g m) where
  callCC :: forall a b. ((a -> RandT g m b) -> RandT g m a) -> RandT g m a
callCC = forall (m :: * -> *) a g b.
CallCC m (a, g) (b, g) -> CallCC (RandT g m) a b
liftCallCC' forall (m :: * -> *) a b. MonadCont m => ((a -> m b) -> m a) -> m a
callCC

instance (MonadError e m) => MonadError e (RandT g m) where
  throwError :: forall a. e -> RandT g m a
throwError = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
  catchError :: forall a. RandT g m a -> (e -> RandT g m a) -> RandT g m a
catchError = forall e (m :: * -> *) a g.
Catch e m (a, g) -> Catch e (RandT g m) a
liftCatch forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError

instance (MonadReader r m, MonadWriter w m, MonadState s m) => MonadRWS r w s (RandT g m)

instance (RandomGen g, Monad m) => MonadRandom (RandT g m) where
  getRandomR :: forall a. Random a => (a, a) -> RandT g m a
getRandomR (a, a)
lohi = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state forall a b. (a -> b) -> a -> b
$ forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (a, a)
lohi
  getRandom :: forall a. Random a => RandT g m a
getRandom = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state forall a b. (a -> b) -> a -> b
$ forall a g. (Random a, RandomGen g) => g -> (a, g)
random
  getRandomRs :: forall a. Random a => (a, a) -> RandT g m [a]
getRandomRs (a, a)
lohi = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
randomRs (a, a)
lohi) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall g. RandomGen g => g -> (g, g)
split
  getRandoms :: forall a. Random a => RandT g m [a]
getRandoms = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first forall a g. (Random a, RandomGen g) => g -> [a]
randoms forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall g. RandomGen g => g -> (g, g)
split

instance (RandomGen g, Monad m) => MonadSplit g (RandT g m) where
  getSplit :: RandT g m g
getSplit = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state forall a b. (a -> b) -> a -> b
$ forall g. RandomGen g => g -> (g, g)
split

instance (Monad m, RandomGen g) => MonadInterleave (RandT g m) where
  interleave :: forall a. RandT g m a -> RandT g m a
interleave (RandT StateT g m a
m) = forall g (m :: * -> *) a. (g -> m (a, g)) -> RandT g m a
liftRandT forall a b. (a -> b) -> a -> b
$ \g
g -> case forall g. RandomGen g => g -> (g, g)
split g
g of
    (g
gl, g
gr) -> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (\(a, g)
p -> (forall a b. (a, b) -> a
fst (a, g)
p, g
gr)) forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
StrictState.runStateT StateT g m a
m g
gl

instance (MonadState s m) => MonadState s (RandT g m) where
  get :: RandT g m s
get = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall s (m :: * -> *). MonadState s m => m s
get
  put :: s -> RandT g m ()
put = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *). MonadState s m => s -> m ()
put

instance PrimMonad m => PrimMonad (RandT s m) where
  type PrimState (RandT s m) = PrimState m
  primitive :: forall a.
(State# (PrimState (RandT s m))
 -> (# State# (PrimState (RandT s m)), a #))
-> RandT s m a
primitive = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive

instance Fail.MonadFail m => Fail.MonadFail (RandT g m) where
  fail :: forall a. String -> RandT g m a
fail = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadFail m => String -> m a
Fail.fail

-- | Uniform lifting of a @callCC@ 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
liftCallCC :: forall (m :: * -> *) a g b.
CallCC m (a, g) (b, g) -> CallCC (RandT g m) a b
liftCallCC CallCC m (a, g) (b, g)
callCC_ (a -> RandT g m b) -> RandT g m a
f = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a s b.
CallCC m (a, s) (b, s) -> CallCC (StateT s m) a b
StrictState.liftCallCC CallCC m (a, g) (b, g)
callCC_ forall a b. (a -> b) -> a -> b
$ \a -> StateT g m b
c -> forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT ((a -> RandT g m b) -> RandT g m a
f (forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> StateT g m b
c))

-- | In-situ lifting of a @callCC@ operation to the new monad.
-- This version uses the current state on entering the continuation.
-- It does not satisfy the uniformity property (see "Control.Monad.Signatures").
liftCallCC' :: CallCC m (a, g) (b, g) -> CallCC (RandT g m) a b
liftCallCC' :: forall (m :: * -> *) a g b.
CallCC m (a, g) (b, g) -> CallCC (RandT g m) a b
liftCallCC' CallCC m (a, g) (b, g)
callCC_ (a -> RandT g m b) -> RandT g m a
f = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a s b.
CallCC m (a, s) (b, s) -> CallCC (StateT s m) a b
StrictState.liftCallCC' CallCC m (a, g) (b, g)
callCC_ forall a b. (a -> b) -> a -> b
$ \a -> StateT g m b
c -> forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT ((a -> RandT g m b) -> RandT g m a
f (forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> StateT g m b
c))

-- | Lift a @catchE@ operation to the new monad.
liftCatch :: Catch e m (a, g) -> Catch e (RandT g m) a
liftCatch :: forall e (m :: * -> *) a g.
Catch e m (a, g) -> Catch e (RandT g m) a
liftCatch Catch e m (a, g)
catchE_ RandT g m a
m e -> RandT g m a
f = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall a b. (a -> b) -> a -> b
$ forall e (m :: * -> *) a s.
Catch e m (a, s) -> Catch e (StateT s m) a
StrictState.liftCatch Catch e m (a, g)
catchE_ (forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT RandT g m a
m) (forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> RandT g m a
f)

-- | Lift a @listen@ operation to the new monad.
liftListen :: (Monad m) => Listen w m (a, g) -> Listen w (RandT g m) a
liftListen :: forall (m :: * -> *) w a g.
Monad m =>
Listen w m (a, g) -> Listen w (RandT g m) a
liftListen Listen w m (a, g)
listen_ RandT g m a
m = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) w a s.
Monad m =>
Listen w m (a, s) -> Listen w (StateT s m) a
StrictState.liftListen Listen w m (a, g)
listen_ (forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT RandT g m a
m)

-- | Lift a @pass@ operation to the new monad.
liftPass :: (Monad m) => Pass w m (a, g) -> Pass w (RandT g m) a
liftPass :: forall (m :: * -> *) w a g.
Monad m =>
Pass w m (a, g) -> Pass w (RandT g m) a
liftPass Pass w m (a, g)
pass_ RandT g m (a, w -> w)
m = forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) w a s.
Monad m =>
Pass w m (a, s) -> Pass w (StateT s m) a
StrictState.liftPass Pass w m (a, g)
pass_ (forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT RandT g m (a, w -> w)
m)

-- | Evaluate a random computation in the `IO` monad, splitting the global
-- standard generator to get a new one for the computation.
evalRandIO :: Rand StdGen a -> IO a
evalRandIO :: forall a. Rand StdGen a -> IO a
evalRandIO Rand StdGen a
t = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall g a. Rand g a -> g -> a
evalRand Rand StdGen a
t) forall (m :: * -> *). MonadIO m => m StdGen
newStdGen

-- | Evaluate a random computation that is embedded in the `IO` monad,
-- splitting the global standard generator to get a new one for the
-- computation.
evalRandTIO :: (MonadIO m) => RandT StdGen m a -> m a
evalRandTIO :: forall (m :: * -> *) a. MonadIO m => RandT StdGen m a -> m a
evalRandTIO RandT StdGen m a
t = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall (m :: * -> *). MonadIO m => m StdGen
newStdGen forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) g a. Monad m => RandT g m a -> g -> m a
evalRandT RandT StdGen m a
t


-- | A proxy that carries information about the type of generator to use with @RandT@
-- monad and its `StatefulGen` instance.
--
-- @since 0.5.3
data RandGen g = RandGen

#if MIN_VERSION_random(1,2,0)
-- |
--
-- @since 0.5.3
instance (Monad m, RandomGen g) => StatefulGen (RandGen g) (RandT g m) where
  uniformWord32R :: Word32 -> RandGen g -> RandT g m Word32
uniformWord32R Word32
r = forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT (forall g. RandomGen g => Word32 -> g -> (Word32, g)
genWord32R Word32
r)
  uniformWord64R :: Word64 -> RandGen g -> RandT g m Word64
uniformWord64R Word64
r = forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT (forall g. RandomGen g => Word64 -> g -> (Word64, g)
genWord64R Word64
r)
  uniformWord8 :: RandGen g -> RandT g m Word8
uniformWord8 = forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT forall g. RandomGen g => g -> (Word8, g)
genWord8
  uniformWord16 :: RandGen g -> RandT g m Word16
uniformWord16 = forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT forall g. RandomGen g => g -> (Word16, g)
genWord16
  uniformWord32 :: RandGen g -> RandT g m Word32
uniformWord32 = forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT forall g. RandomGen g => g -> (Word32, g)
genWord32
  uniformWord64 :: RandGen g -> RandT g m Word64
uniformWord64 = forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT forall g. RandomGen g => g -> (Word64, g)
genWord64
  uniformShortByteString :: Int -> RandGen g -> RandT g m ShortByteString
uniformShortByteString Int
n = forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT (forall g. RandomGen g => Int -> g -> (ShortByteString, g)
genShortByteString Int
n)

-- |
--
-- @since 0.5.3
instance (Monad m, RandomGen g) => RandomGenM (RandGen g) g (RandT g m) where
  applyRandomGenM :: forall a. (g -> (a, g)) -> RandGen g -> RandT g m a
applyRandomGenM = forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT

applyRandT :: Applicative m => (g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT :: forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT g -> (a, g)
f RandGen g
_ = forall g (m :: * -> *) a. (g -> m (a, g)) -> RandT g m a
liftRandT (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. g -> (a, g)
f)
#endif

-- | A `RandT` runner that allows using it with `StatefulGen` restricted actions. Returns
-- the outcome of random computation and the new pseudo-random-number generator
--
-- >>> withRandGen (mkStdGen 2021) uniformM :: IO (Int, StdGen)
-- (6070831465987696718,StdGen {unStdGen = SMGen 4687568268719557181 4805600293067301895})
--
-- @since 0.5.3
withRandGen ::
     g
  -- ^ initial generator
  -> (RandGen g -> RandT g m a)
  -> m (a, g)
  -- ^ return value and final generator
withRandGen :: forall g (m :: * -> *) a.
g -> (RandGen g -> RandT g m a) -> m (a, g)
withRandGen g
g RandGen g -> RandT g m a
action = forall g (m :: * -> *) a. RandT g m a -> g -> m (a, g)
runRandT (RandGen g -> RandT g m a
action forall g. RandGen g
RandGen) g
g

-- | Same as `withRandGen`, but discards the resulting generator.
--
-- >>> withRandGen_ (mkStdGen 2021) uniformM :: IO Int
-- 6070831465987696718
--
-- @since 0.5.3
withRandGen_ ::
     Monad m
  => g
  -- ^ initial generator
  -> (RandGen g -> RandT g m a)
  -> m a
  -- ^ return value and final generator
withRandGen_ :: forall (m :: * -> *) g a.
Monad m =>
g -> (RandGen g -> RandT g m a) -> m a
withRandGen_ g
g RandGen g -> RandT g m a
action = forall (m :: * -> *) g a. Monad m => RandT g m a -> g -> m a
evalRandT (RandGen g -> RandT g m a
action forall g. RandGen g
RandGen) g
g


{- $examples

The @die@ function simulates the roll of a die, picking a number between 1
and 6, inclusive, and returning it in the 'Rand' monad transformer.  Notice
that this code will work with any random number generator @g@.

> die :: (RandomGen g) => Rand g Int
> die = getRandomR (1, 6)

The @dice@ function uses @replicate@ and @sequence@ to simulate the roll of
@n@ dice.

> dice :: (RandomGen g) => Int -> Rand g [Int]
> dice n = sequence (replicate n die)

To extract a value from the 'Rand' monad transformer, we can use 'evalRandIO'.

> main = do
>   values <- evalRandIO (dice 2)
>   putStrLn (show values)

-}