!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~(c) Brent Yorgey 2016BSD3 (see LICENSE)byorgey@gmail.comSafe9;<=? The class , proivides a convenient interface atop a ! operation on a random generator.If x :: m a0 is a computation in some random monad, then  interleave x+ works by splitting the generator, running xP using one half, and using the other half as the final generator state of  interleave x (replacing whatever the final generator state otherwise would have been). This means that computation needing random values which comes after  interleave x6 does not necessarily depend on the computation of x. For example: >>> evalRandIO $ snd <$> ((,) <$> undefined <*> getRandom) *** Exception: Prelude.undefined >>> evalRandIO $ snd <$> ((,) <$> interleave undefined <*> getRandom) 6192322188769041625This 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 randTreeP cannot be evaluated lazily: even though it is cut off at two levels deep by hew 2, 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  interleave , as in  randTreeI6, solves the problem: the generator splits at each NodeQ, so random values in the left and right subtrees are generated independently. hdata Tree = Leaf | Node Int Tree Tree deriving Show hew :: Int -> Tree -> 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 <$> getRandom <*> randTree <*> randTree randTreeI :: Rand StdGen Tree randTreeI = interleave $ Node <$> getRandom <*> randTreeI <*> randTreeI >>> hew 2 <$> evalRandIO randTree Node 2168685089479838995 (Node (-1040559818952481847) Leaf Leaf) (Node ^CInterrupted. >>> hew 2 <$> evalRandIO randTreeI Node 8243316398511136358 (Node 4139784028141790719 Leaf Leaf) (Node 4473998613878251948 Leaf Leaf) The class c 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 .The G operation allows one to obtain two distinct random number generators.See  for details.3With a source of random number supply in hand, the M class allows the programmer to extract random values of a variety of types.Takes a range (lo,hi) and a random number generator gf, and returns a computation that returns a random value uniformly distributed in the closed interval [lo,hi]D, together with a new generator. It is unspecified what happens if lo>hi@. For continuous types there is no requirement that the values lo and hiX are ever produced, but they may be, depending on the implementation and the interval.See  for details. The same as 3, but using a default range determined by the type: For bounded types (instances of  , such as +), the range is normally the whole type.FFor fractional types, the range is normally the semi-closed interval [0,1).For *, the range is (arbitrarily) the range of .See  for details.Plural variant of T, producing an infinite list of random values instead of returning a new generator.See  for details.Plural variant of T, producing an infinite list of random values instead of returning a new generator.See  for details. bSample a random value from a weighted nonempty collection of elements. Crashes with a call to error; if the collection is empty or the total weight is zero. ISample a random value from a weighted collection of elements. Returns Nothing; if the collection is empty or the total weight is zero. qSample a random value from a weighted list. The list must be non-empty and the total weight must be non-zero. 4Sample a random value from a weighted list. Return Nothing5 if the list is empty or the total weight is zero. @Sample a value uniformly from a nonempty collection of elements.CSample a value uniformly from a collection of elements. Return Nothing if the collection is empty.8  !"#$%&'()*+,-./01234567   2  !"#$%&'()*+,-./01234567(c) Brent Yorgey 2016BSD3 (see LICENSE)byorgey@gmail.com experimentalRnon-portable (multi-param classes, functional dependencies, undecidable instances) Trustworthy 9;<=DIR8,A random transformer monad parameterized by:g - The generator.m - The inner monad.The 0 function leaves the generator unchanged, while \ uses the final generator of the first computation as the initial generator of the second.9)A random monad parameterized by the type g of the generator to carry.The 0 function leaves the generator unchanged, while \ uses the final generator of the first computation as the initial generator of the second.:GConstruct a random monad computation from a function. (The inverse of ;.);BUnwrap a random monad computation as a function. (The inverse of :.)<{Evaluate a random computation with the given initial generator and return the final value, discarding the final generator. < m s = fst (; m s)={Evaluate a random computation with the given initial generator and return the final generator, discarding the final value. = m s = snd (; m s)>YMap both the return value and final generator of a computation using the given function. ; (> f m) = f . ; m?? f m executes action m% on a generator modified by applying f. ? f m =  f >> m@OConstruct a random monad computation from an impure function. (The inverse of A.)AJUnwrap a random monad computation as an impure function. (The inverse of @.)B{Evaluate a random computation with the given initial generator and return the final value, discarding the final generator. B m g = liftM fst (A m g)C{Evaluate a random computation with the given initial generator and return the final generator, discarding the final value. C m g = liftM snd (A m g)DYMap both the return value and final generator of a computation using the given function. A (D f m) = f . A mEE f m executes action m% on a generator modified by applying f. E f m =  f >> mFUniform lifting of a callCCj operation to the new monad. This version rolls back to the original state on entering the continuation.GIn-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).HLift a catchE operation to the new monad.ILift a listen operation to the new monad.JLift a pass operation to the new monad.K%Evaluate a random computation in the V monad, splitting the global standard generator to get a new one for the computation.L6Evaluate a random computation that is embedded in the W monad, splitting the global standard generator to get a new one for the computation. 89:pure random transformer(equivalent generator-passing computation;(generator-passing computation to executeinitial generator return value and final generator<(generator-passing computation to executeinitial generator&return value of the random computation=(generator-passing computation to executeinitial generatorfinal generator>?@impure random transformer(equivalent generator-passing computationA(generator-passing computation to executeinitial generator return value and final generatorBCDEFGHIJKLMNOPQRSTU89:;<=>?@ABCDEFGHIJKL9:;<=>?K8@ABCDEFGHIJL89:;<=>?@ABCDEFGHIJKLMNOPQRSTU(c) Brent Yorgey 2016BSD3 (see LICENSE)byorgey@gmail.com experimentalRnon-portable (multi-param classes, functional dependencies, undecidable instances)SafeP 89:;<=>?@ABCDEKL9:;<=>?K8@ABCDEL(c) Brent Yorgey 2016BSD3 (see LICENSE)byorgey@gmail.com experimentalRnon-portable (multi-param classes, functional dependencies, undecidable instances)Safe89:;<=>?@ABCDEFGHIJKL(c) Brent Yorgey 2016BSD3 (see LICENSE)byorgey@gmail.com experimentalRnon-portable (multi-param classes, functional dependencies, undecidable instances) Trustworthy 9;<=DIR`,A random transformer monad parameterized by:g - The generator.m - The inner monad.The 0 function leaves the generator unchanged, while \ uses the final generator of the first computation as the initial generator of the second.a)A random monad parameterized by the type g of the generator to carry.The 0 function leaves the generator unchanged, while \ uses the final generator of the first computation as the initial generator of the second.bGConstruct a random monad computation from a function. (The inverse of c.)cBUnwrap a random monad computation as a function. (The inverse of b.)d{Evaluate a random computation with the given initial generator and return the final value, discarding the final generator. d m s = fst (c m s)e{Evaluate a random computation with the given initial generator and return the final generator, discarding the final value. e m s = snd (c m s)fYMap both the return value and final generator of a computation using the given function. c (f f m) = f . c mgg f m executes action m% on a generator modified by applying f. g f m =  f >> mhOConstruct a random monad computation from an impure function. (The inverse of i.)iJUnwrap a random monad computation as an impure function. (The inverse of h.)j{Evaluate a random computation with the given initial generator and return the final value, discarding the final generator. j m g = liftM fst (i m g)k{Evaluate a random computation with the given initial generator and return the final generator, discarding the final value. k m g = liftM snd (i m g)lYMap both the return value and final generator of a computation using the given function. i (l f m) = f . i mmm f m executes action m% on a generator modified by applying f. m f m =  f >> mnUniform lifting of a callCCj operation to the new monad. This version rolls back to the original state on entering the continuation.oIn-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).pLift a catchE operation to the new monad.qLift a listen operation to the new monad.rLift a pass operation to the new monad.s%Evaluate a random computation in the V monad, splitting the global standard generator to get a new one for the computation.t6Evaluate a random computation that is embedded in the W monad, splitting the global standard generator to get a new one for the computation. `abpure random transformer(equivalent generator-passing computationc(generator-passing computation to executeinitial generator return value and final generatord(generator-passing computation to executeinitial generator&return value of the random computatione(generator-passing computation to executeinitial generatorfinal generatorfghimpure random transformer(equivalent generator-passing computationi(generator-passing computation to executeinitial generator return value and final generatorjklmnopqrstuvwxyz{|}`abcdefghijklmnopqrstabcdefgs`hijklmtnopqr`abcdefghijklmnopqrstuvwxyz{|}(c) Brent Yorgey 2016BSD3 (see LICENSE)byorgey@gmail.com experimentalRnon-portable (multi-param classes, functional dependencies, undecidable instances)SafeP `abcdefghijklmstabcdefgs`hijklmt(c) Brent Yorgey 2016BSD3 (see LICENSE)byorgey@gmail.com experimentalRnon-portable (multi-param classes, functional dependencies, undecidable instances)SafeP 89:;<=>?@ABCDEKL      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijhiklmnopqrstopuhivhiwhixlyzly{|}~op@llylylylylylyllllllllllllllllllllllllllllylylylylylylylylylyly@&MonadRandom-0.5-InYiOZYIbHv2TCJHvMGquiControl.Monad.Random.ClassControl.Monad.Trans.Random.Lazy!Control.Monad.Trans.Random.StrictControl.Monad.Random.LazyControl.Monad.Trans.RandomControl.Monad.Random.StrictControl.Monad.RandomMonadInterleave interleave MonadSplitgetSplit MonadRandom getRandomR getRandom getRandomRs getRandomsweighted weightedMayfromList fromListMayuniform uniformMay$fMonadInterleaveWriterT$fMonadInterleaveWriterT0$fMonadInterleaveStateT$fMonadInterleaveStateT0$fMonadInterleaveReaderT$fMonadInterleaveRWST$fMonadInterleaveRWST0$fMonadInterleaveMaybeT$fMonadInterleaveListT$fMonadInterleaveIdentityT$fMonadInterleaveExceptT$fMonadInterleaveErrorT$fMonadInterleaveContT$fMonadSplitgWriterT$fMonadSplitgWriterT0$fMonadSplitgStateT$fMonadSplitgStateT0$fMonadSplitgReaderT$fMonadSplitgRWST$fMonadSplitgRWST0$fMonadSplitgMaybeT$fMonadSplitgListT$fMonadSplitgIdentityT$fMonadSplitgExceptT$fMonadSplitgErrorT$fMonadSplitgContT$fMonadSplitStdGenIO$fMonadRandomWriterT$fMonadRandomWriterT0$fMonadRandomStateT$fMonadRandomStateT0$fMonadRandomReaderT$fMonadRandomRWST$fMonadRandomRWST0$fMonadRandomMaybeT$fMonadRandomListT$fMonadRandomIdentityT$fMonadRandomExceptT$fMonadRandomErrorT$fMonadRandomContT$fMonadRandomIORandTRandliftRandrunRandevalRandexecRandmapRandwithRand liftRandTrunRandT evalRandT execRandTmapRandT withRandT liftCallCC liftCallCC' liftCatch liftListenliftPass evalRandIO evalRandTIO$fMonadFailRandT$fPrimMonadRandT$fMonadStatesRandT$fMonadInterleaveRandT$fMonadSplitgRandT$fMonadRandomRandT$fMonadRWSrwsRandT$fMonadErroreRandT$fMonadContRandT$fFunctorRandT$fApplicativeRandT$fAlternativeRandT $fMonadRandT$fMonadPlusRandT$fMonadTransRandT$fMonadIORandT$fMonadFixRandT$fMonadReaderRandT$fMonadWriterRandT!random-1.1-54KmMHXjttlERYcr1mvsAe System.RandomsplitrandomRbaseGHC.EnumBoundedghc-prim GHC.TypesChar integer-gmpGHC.Integer.TypeIntegerIntrandomrandomRsrandomsGHC.Basereturn>>= mtl-2.2.1-6qsR1PHUy5lL47Hpoa4jCMControl.Monad.State.ClassmodifyIOunRandT Control.MonadguardjoinMonadfail>>FunctorfmapControl.Monad.FixMonadFixmfixData.TraversablemapMsequenceControl.Monad.IO.ClassMonadIOliftIOmfilter<$!>unless replicateM_ replicateMfoldM_foldM zipWithM_zipWithM mapAndUnzipMforever<=<>=>filterMforM Data.Foldablemsum sequence_forM_mapM_ Data.Functionfix Data.FunctorvoidapliftM5liftM4liftM3liftM2liftMwhen=<< MonadPlusmzeromplustransformers-0.5.2.0Control.Monad.Trans.Class MonadTranslift