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

{- |
Module       :  Control.Monad.Trans.Random.Lazy
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)

Lazy random monads, passing a random number generator through a computation.
See below for examples.

For a strict version with the same interface, see
"Control.Monad.Trans.Random.Strict".
-}

module Control.Monad.Trans.Random.Lazy
  ( -- * The Rand monad transformer
    Rand,
    liftRand,
    runRand,
    evalRand,
    execRand,
    mapRand,
    withRand,
    evalRandIO,
    -- * The RandT monad transformer
    RandT,
    liftRandT,
    runRandT,
    evalRandT,
    execRandT,
    mapRandT,
    withRandT,
    -- * Lifting other operations
    liftCallCC,
    liftCallCC',
    liftCatch,
    liftListen,
    liftPass,
    evalRandTIO,
    -- * 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.Lazy as LazyState
import Control.Monad.Trans.Random.Strict (RandGen(..))
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 :: (g -> (a, g)) -> Rand g a
liftRand = StateT g Identity a -> Rand g a
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g Identity a -> Rand g a)
-> ((g -> (a, g)) -> StateT g Identity a)
-> (g -> (a, g))
-> Rand g a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g -> (a, g)) -> StateT g Identity a
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 :: Rand g a -> g -> (a, g)
runRand Rand g a
t = Identity (a, g) -> (a, g)
forall a. Identity a -> a
runIdentity (Identity (a, g) -> (a, g))
-> (g -> Identity (a, g)) -> g -> (a, g)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rand g a -> g -> Identity (a, g)
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 :: Rand g a -> g -> a
evalRand Rand g a
t = Identity a -> a
forall a. Identity a -> a
runIdentity (Identity a -> a) -> (g -> Identity a) -> g -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rand g a -> g -> Identity a
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 :: Rand g a -> g -> g
execRand Rand g a
t = Identity g -> g
forall a. Identity a -> a
runIdentity (Identity g -> g) -> (g -> Identity g) -> g -> g
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rand g a -> g -> Identity g
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 :: ((a, g) -> (b, g)) -> Rand g a -> Rand g b
mapRand (a, g) -> (b, g)
f = (Identity (a, g) -> Identity (b, g)) -> Rand g a -> Rand g b
forall (m :: * -> *) a g (n :: * -> *) b.
(m (a, g) -> n (b, g)) -> RandT g m a -> RandT g n b
mapRandT (((a, g) -> (b, g)) -> Identity (a, g) -> Identity (b, g)
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 :: (g -> g) -> Rand g a -> Rand g a
withRand = (g -> g) -> Rand g a -> Rand g a
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 { RandT g m a -> StateT g m a
unRandT :: LazyState.StateT g m a }
  deriving (a -> RandT g m b -> RandT g m a
(a -> b) -> RandT g m a -> RandT g m b
(forall a b. (a -> b) -> RandT g m a -> RandT g m b)
-> (forall a b. a -> RandT g m b -> RandT g m a)
-> Functor (RandT g m)
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
<$ :: 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 :: (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, Functor (RandT g m)
a -> RandT g m a
Functor (RandT g m)
-> (forall a. a -> RandT g m a)
-> (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 a b. RandT g m a -> RandT g m b -> RandT g m b)
-> (forall a b. RandT g m a -> RandT g m b -> RandT g m a)
-> Applicative (RandT g m)
RandT g m a -> RandT g m b -> RandT g m b
RandT g m a -> RandT g m b -> RandT g m a
RandT g m (a -> b) -> RandT g m a -> RandT g m b
(a -> b -> c) -> RandT g m a -> RandT g m b -> RandT g m c
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
<* :: 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
*> :: 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 :: (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
<*> :: 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 :: a -> RandT g m a
$cpure :: forall g (m :: * -> *) a. Monad m => a -> RandT g m a
$cp1Applicative :: forall g (m :: * -> *). Monad m => Functor (RandT g m)
Applicative, Applicative (RandT g m)
RandT g m a
Applicative (RandT g m)
-> (forall a. RandT g m a)
-> (forall a. RandT g m a -> RandT g m 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])
-> Alternative (RandT g m)
RandT g m a -> RandT g m a -> RandT g m a
RandT g m a -> RandT g m [a]
RandT g m a -> RandT g m [a]
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 :: RandT g m a -> RandT g m [a]
$cmany :: forall g (m :: * -> *) a.
MonadPlus m =>
RandT g m a -> RandT g m [a]
some :: RandT g m a -> RandT g m [a]
$csome :: forall g (m :: * -> *) a.
MonadPlus m =>
RandT g m a -> RandT g m [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 :: RandT g m a
$cempty :: forall g (m :: * -> *) a. MonadPlus m => RandT g m a
$cp1Alternative :: forall g (m :: * -> *). MonadPlus m => Applicative (RandT g m)
Alternative, Applicative (RandT g m)
a -> RandT g m a
Applicative (RandT g m)
-> (forall a b. RandT g m a -> (a -> RandT g m b) -> RandT g m b)
-> (forall a b. RandT g m a -> RandT g m b -> RandT g m b)
-> (forall a. a -> RandT g m a)
-> Monad (RandT g m)
RandT g m a -> (a -> RandT g m b) -> RandT g m b
RandT g m a -> RandT g m b -> RandT g m b
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 :: a -> RandT g m a
$creturn :: forall g (m :: * -> *) a. Monad m => a -> RandT g m a
>> :: 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
>>= :: 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
$cp1Monad :: forall g (m :: * -> *). Monad m => Applicative (RandT g m)
Monad, Monad (RandT g m)
Alternative (RandT g m)
RandT g m a
Alternative (RandT g m)
-> Monad (RandT g m)
-> (forall a. RandT g m a)
-> (forall a. RandT g m a -> RandT g m a -> RandT g m a)
-> MonadPlus (RandT g m)
RandT g m a -> RandT g m a -> RandT g m a
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 :: 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 :: RandT g m a
$cmzero :: forall g (m :: * -> *) a. MonadPlus m => RandT g m a
$cp2MonadPlus :: forall g (m :: * -> *). MonadPlus m => Monad (RandT g m)
$cp1MonadPlus :: forall g (m :: * -> *). MonadPlus m => Alternative (RandT g m)
MonadPlus, m a -> RandT g m a
(forall (m :: * -> *) a. Monad m => m a -> RandT g m a)
-> MonadTrans (RandT g)
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 :: m a -> RandT g m a
$clift :: forall g (m :: * -> *) a. Monad m => m a -> RandT g m a
MonadTrans, Monad (RandT g m)
Monad (RandT g m)
-> (forall a. IO a -> RandT g m a) -> MonadIO (RandT g m)
IO a -> RandT g m a
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 :: IO a -> RandT g m a
$cliftIO :: forall g (m :: * -> *) a. MonadIO m => IO a -> RandT g m a
$cp1MonadIO :: forall g (m :: * -> *). MonadIO m => Monad (RandT g m)
MonadIO, Monad (RandT g m)
Monad (RandT g m)
-> (forall a. (a -> RandT g m a) -> RandT g m a)
-> MonadFix (RandT g m)
(a -> RandT g m a) -> RandT g m a
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 :: (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
$cp1MonadFix :: forall g (m :: * -> *). MonadFix m => Monad (RandT g m)
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 :: (g -> m (a, g)) -> RandT g m a
liftRandT = StateT g m a -> RandT g m a
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m a -> RandT g m a)
-> ((g -> m (a, g)) -> StateT g m a)
-> (g -> m (a, g))
-> RandT g m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g -> m (a, g)) -> StateT g m a
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
LazyState.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 :: RandT g m a -> g -> m (a, g)
runRandT = StateT g m a -> g -> m (a, g)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
LazyState.runStateT (StateT g m a -> g -> m (a, g))
-> (RandT g m a -> StateT g m a) -> RandT g m a -> g -> m (a, g)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RandT g m a -> StateT g m a
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 :: RandT g m a -> g -> m a
evalRandT = StateT g m a -> g -> m a
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
LazyState.evalStateT (StateT g m a -> g -> m a)
-> (RandT g m a -> StateT g m a) -> RandT g m a -> g -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RandT g m a -> StateT g m a
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 :: RandT g m a -> g -> m g
execRandT = StateT g m a -> g -> m g
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
LazyState.execStateT (StateT g m a -> g -> m g)
-> (RandT g m a -> StateT g m a) -> RandT g m a -> g -> m g
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RandT g m a -> StateT g m a
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 :: (m (a, g) -> n (b, g)) -> RandT g m a -> RandT g n b
mapRandT m (a, g) -> n (b, g)
f = StateT g n b -> RandT g n b
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g n b -> RandT g n b)
-> (RandT g m a -> StateT g n b) -> RandT g m a -> RandT g n b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (m (a, g) -> n (b, g)) -> StateT g m a -> StateT g n b
forall (m :: * -> *) a s (n :: * -> *) b.
(m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
LazyState.mapStateT m (a, g) -> n (b, g)
f (StateT g m a -> StateT g n b)
-> (RandT g m a -> StateT g m a) -> RandT g m a -> StateT g n b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RandT g m a -> StateT g m a
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 :: (g -> g) -> RandT g m a -> RandT g m a
withRandT g -> g
f = StateT g m a -> RandT g m a
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m a -> RandT g m a)
-> (RandT g m a -> StateT g m a) -> RandT g m a -> RandT g m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g -> g) -> StateT g m a -> StateT g m a
forall s (m :: * -> *) a. (s -> s) -> StateT s m a -> StateT s m a
LazyState.withStateT g -> g
f (StateT g m a -> StateT g m a)
-> (RandT g m a -> StateT g m a) -> RandT g m a -> StateT g m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RandT g m a -> StateT g m a
forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT

instance (MonadCont m) => MonadCont (RandT g m) where
  callCC :: ((a -> RandT g m b) -> RandT g m a) -> RandT g m a
callCC = CallCC m (a, g) (b, g)
-> ((a -> RandT g m b) -> RandT g m a) -> RandT g m a
forall (m :: * -> *) a g b.
CallCC m (a, g) (b, g) -> CallCC (RandT g m) a b
liftCallCC' CallCC m (a, g) (b, g)
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 :: e -> RandT g m a
throwError = m a -> RandT g m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> RandT g m a) -> (e -> m a) -> e -> RandT g m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
  catchError :: RandT g m a -> (e -> RandT g m a) -> RandT g m a
catchError = Catch e m (a, g)
-> RandT g m a -> (e -> RandT g m a) -> RandT g m a
forall e (m :: * -> *) a g.
Catch e m (a, g) -> Catch e (RandT g m) a
liftCatch Catch e m (a, g)
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 :: (a, a) -> RandT g m a
getRandomR (a, a)
lohi = StateT g m a -> RandT g m a
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m a -> RandT g m a)
-> ((g -> (a, g)) -> StateT g m a) -> (g -> (a, g)) -> RandT g m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g -> (a, g)) -> StateT g m a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state ((g -> (a, g)) -> RandT g m a) -> (g -> (a, g)) -> RandT g m a
forall a b. (a -> b) -> a -> b
$ (a, a) -> g -> (a, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (a, a)
lohi
  getRandom :: RandT g m a
getRandom = StateT g m a -> RandT g m a
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m a -> RandT g m a)
-> ((g -> (a, g)) -> StateT g m a) -> (g -> (a, g)) -> RandT g m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g -> (a, g)) -> StateT g m a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state ((g -> (a, g)) -> RandT g m a) -> (g -> (a, g)) -> RandT g m a
forall a b. (a -> b) -> a -> b
$ g -> (a, g)
forall a g. (Random a, RandomGen g) => g -> (a, g)
random
  getRandomRs :: (a, a) -> RandT g m [a]
getRandomRs (a, a)
lohi = StateT g m [a] -> RandT g m [a]
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m [a] -> RandT g m [a])
-> ((g -> ([a], g)) -> StateT g m [a])
-> (g -> ([a], g))
-> RandT g m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g -> ([a], g)) -> StateT g m [a]
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state ((g -> ([a], g)) -> RandT g m [a])
-> (g -> ([a], g)) -> RandT g m [a]
forall a b. (a -> b) -> a -> b
$ (g -> [a]) -> (g, g) -> ([a], g)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first ((a, a) -> g -> [a]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
randomRs (a, a)
lohi) ((g, g) -> ([a], g)) -> (g -> (g, g)) -> g -> ([a], g)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. g -> (g, g)
forall g. RandomGen g => g -> (g, g)
split
  getRandoms :: RandT g m [a]
getRandoms = StateT g m [a] -> RandT g m [a]
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m [a] -> RandT g m [a])
-> ((g -> ([a], g)) -> StateT g m [a])
-> (g -> ([a], g))
-> RandT g m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g -> ([a], g)) -> StateT g m [a]
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state ((g -> ([a], g)) -> RandT g m [a])
-> (g -> ([a], g)) -> RandT g m [a]
forall a b. (a -> b) -> a -> b
$ (g -> [a]) -> (g, g) -> ([a], g)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first g -> [a]
forall a g. (Random a, RandomGen g) => g -> [a]
randoms ((g, g) -> ([a], g)) -> (g -> (g, g)) -> g -> ([a], g)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. g -> (g, g)
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 = StateT g m g -> RandT g m g
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m g -> RandT g m g)
-> ((g -> (g, g)) -> StateT g m g) -> (g -> (g, g)) -> RandT g m g
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g -> (g, g)) -> StateT g m g
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state ((g -> (g, g)) -> RandT g m g) -> (g -> (g, g)) -> RandT g m g
forall a b. (a -> b) -> a -> b
$ g -> (g, g)
forall g. RandomGen g => g -> (g, g)
split

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

instance (MonadState s m) => MonadState s (RandT g m) where
  get :: RandT g m s
get = m s -> RandT g m s
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m s
forall s (m :: * -> *). MonadState s m => m s
get
  put :: s -> RandT g m ()
put = m () -> RandT g m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RandT g m ()) -> (s -> m ()) -> s -> RandT g m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> m ()
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 :: (State# (PrimState (RandT s m))
 -> (# State# (PrimState (RandT s m)), a #))
-> RandT s m a
primitive = m a -> RandT s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> RandT s m a)
-> ((State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a)
-> (State# (PrimState m) -> (# State# (PrimState m), a #))
-> RandT s m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
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 :: String -> RandT g m a
fail = m a -> RandT g m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> RandT g m a) -> (String -> m a) -> String -> RandT g m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> m a
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 :: 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 = StateT g m a -> RandT g m a
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m a -> RandT g m a) -> StateT g m a -> RandT g m a
forall a b. (a -> b) -> a -> b
$ CallCC m (a, g) (b, g) -> CallCC (StateT g m) a b
forall (m :: * -> *) a s b.
CallCC m (a, s) (b, s) -> CallCC (StateT s m) a b
LazyState.liftCallCC CallCC m (a, g) (b, g)
callCC_ CallCC (StateT g m) a b -> CallCC (StateT g m) a b
forall a b. (a -> b) -> a -> b
$ \a -> StateT g m b
c -> RandT g m a -> StateT g m a
forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT ((a -> RandT g m b) -> RandT g m a
f (StateT g m b -> RandT g m b
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m b -> RandT g m b)
-> (a -> StateT g m b) -> a -> RandT g m b
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' :: 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 = StateT g m a -> RandT g m a
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m a -> RandT g m a) -> StateT g m a -> RandT g m a
forall a b. (a -> b) -> a -> b
$ CallCC m (a, g) (b, g) -> CallCC (StateT g m) a b
forall (m :: * -> *) a s b.
CallCC m (a, s) (b, s) -> CallCC (StateT s m) a b
LazyState.liftCallCC' CallCC m (a, g) (b, g)
callCC_ CallCC (StateT g m) a b -> CallCC (StateT g m) a b
forall a b. (a -> b) -> a -> b
$ \a -> StateT g m b
c -> RandT g m a -> StateT g m a
forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT ((a -> RandT g m b) -> RandT g m a
f (StateT g m b -> RandT g m b
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m b -> RandT g m b)
-> (a -> StateT g m b) -> a -> RandT g m b
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 :: 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 = StateT g m a -> RandT g m a
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m a -> RandT g m a) -> StateT g m a -> RandT g m a
forall a b. (a -> b) -> a -> b
$ Catch e m (a, g) -> Catch e (StateT g m) a
forall e (m :: * -> *) a s.
Catch e m (a, s) -> Catch e (StateT s m) a
LazyState.liftCatch Catch e m (a, g)
catchE_ (RandT g m a -> StateT g m a
forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT RandT g m a
m) (RandT g m a -> StateT g m a
forall g (m :: * -> *) a. RandT g m a -> StateT g m a
unRandT (RandT g m a -> StateT g m a)
-> (e -> RandT g m a) -> e -> StateT g m a
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 :: Listen w m (a, g) -> Listen w (RandT g m) a
liftListen Listen w m (a, g)
listen_ RandT g m a
m = StateT g m (a, w) -> RandT g m (a, w)
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m (a, w) -> RandT g m (a, w))
-> StateT g m (a, w) -> RandT g m (a, w)
forall a b. (a -> b) -> a -> b
$ Listen w m (a, g) -> Listen w (StateT g m) a
forall (m :: * -> *) w a s.
Monad m =>
Listen w m (a, s) -> Listen w (StateT s m) a
LazyState.liftListen Listen w m (a, g)
listen_ (RandT g m a -> StateT g m a
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 :: 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 = StateT g m a -> RandT g m a
forall g (m :: * -> *) a. StateT g m a -> RandT g m a
RandT (StateT g m a -> RandT g m a) -> StateT g m a -> RandT g m a
forall a b. (a -> b) -> a -> b
$ Pass w m (a, g) -> Pass w (StateT g m) a
forall (m :: * -> *) w a s.
Monad m =>
Pass w m (a, s) -> Pass w (StateT s m) a
LazyState.liftPass Pass w m (a, g)
pass_ (RandT g m (a, w -> w) -> StateT g m (a, w -> w)
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 :: Rand StdGen a -> IO a
evalRandIO Rand StdGen a
t = (StdGen -> a) -> IO StdGen -> IO a
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Rand StdGen a -> StdGen -> a
forall g a. Rand g a -> g -> a
evalRand Rand StdGen a
t) IO StdGen
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 :: RandT StdGen m a -> m a
evalRandTIO RandT StdGen m a
t = IO StdGen -> m StdGen
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO StdGen
forall (m :: * -> *). MonadIO m => m StdGen
newStdGen m StdGen -> (StdGen -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= RandT StdGen m a -> StdGen -> m a
forall (m :: * -> *) g a. Monad m => RandT g m a -> g -> m a
evalRandT RandT StdGen m a
t

#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 = (g -> (Word32, g)) -> RandGen g -> RandT g m Word32
forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT (Word32 -> g -> (Word32, g)
forall g. RandomGen g => Word32 -> g -> (Word32, g)
genWord32R Word32
r)
  uniformWord64R :: Word64 -> RandGen g -> RandT g m Word64
uniformWord64R Word64
r = (g -> (Word64, g)) -> RandGen g -> RandT g m Word64
forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT (Word64 -> g -> (Word64, g)
forall g. RandomGen g => Word64 -> g -> (Word64, g)
genWord64R Word64
r)
  uniformWord8 :: RandGen g -> RandT g m Word8
uniformWord8 = (g -> (Word8, g)) -> RandGen g -> RandT g m Word8
forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT g -> (Word8, g)
forall g. RandomGen g => g -> (Word8, g)
genWord8
  uniformWord16 :: RandGen g -> RandT g m Word16
uniformWord16 = (g -> (Word16, g)) -> RandGen g -> RandT g m Word16
forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT g -> (Word16, g)
forall g. RandomGen g => g -> (Word16, g)
genWord16
  uniformWord32 :: RandGen g -> RandT g m Word32
uniformWord32 = (g -> (Word32, g)) -> RandGen g -> RandT g m Word32
forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT g -> (Word32, g)
forall g. RandomGen g => g -> (Word32, g)
genWord32
  uniformWord64 :: RandGen g -> RandT g m Word64
uniformWord64 = (g -> (Word64, g)) -> RandGen g -> RandT g m Word64
forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT g -> (Word64, g)
forall g. RandomGen g => g -> (Word64, g)
genWord64
  uniformShortByteString :: Int -> RandGen g -> RandT g m ShortByteString
uniformShortByteString Int
n = (g -> (ShortByteString, g))
-> RandGen g -> RandT g m ShortByteString
forall (m :: * -> *) g a.
Applicative m =>
(g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT (Int -> g -> (ShortByteString, g)
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 :: (g -> (a, g)) -> RandGen g -> RandT g m a
applyRandomGenM = (g -> (a, g)) -> RandGen g -> RandT g m a
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 :: (g -> (a, g)) -> RandGen g -> RandT g m a
applyRandT g -> (a, g)
f RandGen g
_ = (g -> m (a, g)) -> RandT g m a
forall g (m :: * -> *) a. (g -> m (a, g)) -> RandT g m a
liftRandT ((a, g) -> m (a, g)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a, g) -> m (a, g)) -> (g -> (a, g)) -> g -> m (a, g)
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 :: g -> (RandGen g -> RandT g m a) -> m (a, g)
withRandGen g
g RandGen g -> RandT g m a
action = RandT g m a -> g -> m (a, g)
forall g (m :: * -> *) a. RandT g m a -> g -> m (a, g)
runRandT (RandGen g -> RandT g m a
action RandGen g
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_ :: g -> (RandGen g -> RandT g m a) -> m a
withRandGen_ g
g RandGen g -> RandT g m a
action = RandT g m a -> g -> m a
forall (m :: * -> *) g a. Monad m => RandT g m a -> g -> m a
evalRandT (RandGen g -> RandT g m a
action RandGen g
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)

-}