Copyright (c) Brent Yorgey 2016 BSD3 (see LICENSE) byorgey@gmail.com experimental non-portable (multi-param classes, functional dependencies, undecidable instances) Trustworthy Haskell2010

Description

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.

Synopsis

# The Rand monad transformer

type Rand g = RandT g Identity Source #

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.

Arguments

 :: (g -> (a, g)) pure random transformer -> Rand g a equivalent generator-passing computation

Construct a random monad computation from a function. (The inverse of runRand.)

Arguments

 :: Rand g a generator-passing computation to execute -> g initial generator -> (a, g) return value and final generator

Unwrap a random monad computation as a function. (The inverse of liftRand.)

Arguments

 :: Rand g a generator-passing computation to execute -> g initial generator -> a return value of the random computation

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)

Arguments

 :: Rand g a generator-passing computation to execute -> g initial generator -> g final generator

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)

mapRand :: ((a, g) -> (b, g)) -> Rand g a -> Rand g b Source #

Map both the return value and final generator of a computation using the given function.

• runRand (mapRand f m) = f . runRand m

withRand :: (g -> g) -> Rand g a -> Rand g a Source #

withRand f m executes action m on a generator modified by applying f.

• withRand f m = modify f >> m

Evaluate a random computation in the IO monad, splitting the global standard generator to get a new one for the computation.

# The RandT monad transformer

data RandT g m a Source #

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.

Instances

Arguments

 :: (g -> m (a, g)) impure random transformer -> RandT g m a equivalent generator-passing computation

Construct a random monad computation from an impure function. (The inverse of runRandT.)

Arguments

 :: RandT g m a generator-passing computation to execute -> g initial generator -> m (a, g) return value and final generator

Unwrap a random monad computation as an impure function. (The inverse of liftRandT.)

evalRandT :: Monad m => RandT g m a -> g -> m a Source #

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)

execRandT :: Monad m => RandT g m a -> g -> m g Source #

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)

mapRandT :: (m (a, g) -> n (b, g)) -> RandT g m a -> RandT g n b Source #

Map both the return value and final generator of a computation using the given function.

• runRandT (mapRandT f m) = f . runRandT m

withRandT :: (g -> g) -> RandT g m a -> RandT g m a Source #

withRandT f m executes action m on a generator modified by applying f.

• withRandT f m = modify f >> m

# Lifting other operations

liftCallCC :: CallCC m (a, g) (b, g) -> CallCC (RandT g m) a b Source #

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

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

liftCatch :: Catch e m (a, g) -> Catch e (RandT g m) a Source #

Lift a catchE operation to the new monad.

liftListen :: Monad m => Listen w m (a, g) -> Listen w (RandT g m) a Source #

Lift a listen operation to the new monad.

liftPass :: Monad m => Pass w m (a, g) -> Pass w (RandT g m) a Source #

Lift a pass operation to the new monad.

evalRandTIO :: MonadIO m => RandT StdGen m a -> m a Source #

Evaluate a random computation that is embedded in the IO monad, splitting the global standard generator to get a new one for the computation.

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