-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Random number generation -- -- Random number generation based on orthogonal typeclasses for entropy -- sources and random variable distributions, all served up on a monadic -- platter. Aspires to be useful in an idiomatic way in both "pure" and -- "impure" styles, as well as reasonably fast. May not yet meet the -- latter goal, but I think the former is starting to shape up nicely. @package random-fu @version 0.0.0.2 -- | A few little functions I found myself writing inline over and over -- again. -- -- Note that these need to be checked to ensure proper behavior on -- big-endian systems. They are probably not right at the moment. module Data.Random.Internal.Words wordsToBytes :: [Word64] -> [Word8] wordToBytes :: Word64 -> [Word8] bytesToWords :: [Word8] -> [Word64] bytesToWord :: [Word8] -> Word64 module Data.Random.Source -- | A typeclass for monads with a chosen source of entropy. For example, -- RVar is such a monad - the source from which it is (eventually) -- sampled is the only source from which a random variable is permitted -- to draw, so when directly requesting entropy for a random variable -- these functions are used. -- -- The minimal definition is either getRandomBytes or -- getRandomWords. class (Monad m) => MonadRandom m getRandomBytes :: (MonadRandom m) => Int -> m [Word8] getRandomWords :: (MonadRandom m) => Int -> m [Word64] -- | A source of entropy which can be used in the given monad. -- -- The minimal definition is either getRandomBytesFrom or -- getRandomWordsFrom class (Monad m) => RandomSource m s getRandomBytesFrom :: (RandomSource m s) => s -> Int -> m [Word8] getRandomWordsFrom :: (RandomSource m s) => s -> Int -> m [Word64] instance (Monad m) => RandomSource m (Int -> m [Word64]) instance (Monad m) => RandomSource m (Int -> m [Word8]) module Data.Random.Source.DevRandom -- | On systems that have it, /dev/random is a handy-dandy ready-to-use -- source of nonsense. data DevRandom DevRandom :: DevRandom instance RandomSource IO DevRandom module Data.Random.Source.StdGen getRandomBytesFromStdGenIO :: Int -> IO [Word8] -- | Given a mutable reference to a RandomGen generator, we can make -- a RandomSource usable in any monad in which the reference can -- be modified. -- -- For example, if x :: TVar StdGen, -- getRandomBytesFromRandomGenRef x can be used as a -- RandomSource in IO, STM, or any monad which is an -- instance of MonadIO. It's generally probably better to use -- getRandomWordsFromRandomGenRef though, as this one is likely to -- throw away a lot of perfectly good entropy. getRandomBytesFromRandomGenRef :: (ModifyRef sr m g, RandomGen g) => sr -> Int -> m [Word8] -- | Similarly, getRandomWordsFromRandomGenState x can be used in -- any "state" monad in the mtl sense whose state is a RandomGen -- generator. Additionally, the standard mtl state monads have -- MonadRandom instances which do precisely that, allowing an easy -- conversion of RVars and other Distribution instances to "pure" random -- variables. getRandomBytesFromRandomGenState :: (RandomGen g, MonadState g m) => Int -> m [Word8] -- | See getRandomBytesFromRandomGenRef getRandomWordsFromRandomGenRef :: (ModifyRef sr m g, RandomGen g) => sr -> Int -> m [Word64] -- | See getRandomBytesFromRandomGenState getRandomWordsFromRandomGenState :: (RandomGen g, MonadState g m) => Int -> m [Word64] instance (Monad m) => MonadRandom (StateT StdGen m) instance MonadRandom (State StdGen) instance (ModifyRef (STRef s StdGen) m StdGen) => RandomSource m (STRef s StdGen) instance (ModifyRef (TVar StdGen) m StdGen) => RandomSource m (TVar StdGen) instance (ModifyRef (IORef StdGen) m StdGen) => RandomSource m (IORef StdGen) module Data.Random.Source.PureMT -- | Given a mutable reference to a PureMT generator, we can make a -- RandomSource usable in any monad in which the reference can be -- modified. -- -- For example, if x :: TVar PureMT, getRandomWordsFromMTRef -- x can be used as a RandomSource in IO, STM, -- or any monad which is an instance of MonadIO. getRandomWordsFromMTRef :: (ModifyRef sr m PureMT) => sr -> Int -> m [Word64] -- | Similarly, getRandomWordsFromMTState x can be used in any -- "state" monad in the mtl sense whose state is a PureMT -- generator. Additionally, the standard mtl state monads have -- MonadRandom instances which do precisely that, allowing an easy -- conversion of RVars and other Distribution instances to "pure" random -- variables. getRandomWordsFromMTState :: (MonadState PureMT m) => Int -> m [Word64] instance (Monad m) => MonadRandom (StateT PureMT m) instance MonadRandom (State PureMT) module Data.Random.Source.Std -- | A token representing the "standard" entropy source in a -- MonadRandom monad. Its sole purpose is to make the following -- true (when the types check): -- --
--   sampleFrom StdRandom === sample
--   
data StdRandom StdRandom :: StdRandom instance (MonadRandom m) => RandomSource m StdRandom -- | "Classification systems" - for a motivating example, see the -- implementation of the Uniform distribution. Basically, I would like to -- make instances like: -- --
--   instance RealFloat a => Distribution Uniform a where ...
--   instance Integral a =>  Distribution Uniform a where ...
--   
-- -- and so on. However, this is not sound - what happens if someone comes -- along and makes a type that's an instance of both Integral and -- RealFloat? -- -- So, we introduce a classification system based on phantom types, so -- that each type can be unambiguously declared to be "intensionally" -- Integral, Floating, or whatever. -- -- Now, obviously it'd be nice not to clutter the Distribution typeclass -- with extra phantom types that the end user shouldn't care about. Hence -- the pattern of introducing typeclasses such as -- UniformByClassification -- -- Now, if a new type comes along that is Integral, a single declaration -- of the following form suffices to attach it to all such Distribution -- instances: -- --
--   instance Classification NumericType t IntegralType
--   
-- -- Not quite as automagic as the Integral a => Distribution -- foo case, but a bit closer. Not only that, it leaves open the -- possibility that a user may bring in a type that is "mostly" integral, -- and has an Integral instance, but should be handled differently for -- purposes of uniform random number generation. In such a case, the user -- may introduce a new classification of their own and provide the -- required instances for that classification. -- -- All in all, although it is not yet well-tested, it has the "feel" of a -- good compromise. module Data.Random.Internal.Classification -- | classificiation system, experimental -- -- -- -- The functional dependency, aside from being important because the -- relation is functional, allows the classification system to be -- "discharged" in cases such as the following: -- --
--   class Classification SomeCS t c => FooByClassification t c where ...
--   instance FooByClassification t c => Foo t where ...
--   
-- -- Thus the class of interest to the end user need not display anything -- at all about the classification system, except in the superclasses of -- the classes in the contexts of some of its instances. class Classification c t tc | c t -> tc -- | A simple classification system covering the cases we care about when -- sampling distributions. Loosely, these are the reasons we care: -- -- data NumericType data IntegralType data FractionalType data EnumType instance Classification NumericType Ordering EnumType instance Classification NumericType () EnumType instance Classification NumericType Bool EnumType instance Classification NumericType Char EnumType instance Classification NumericType (Ratio a) FractionalType instance Classification NumericType Double FractionalType instance Classification NumericType Float FractionalType instance Classification NumericType Integer IntegralType instance Classification NumericType Word64 IntegralType instance Classification NumericType Word32 IntegralType instance Classification NumericType Word16 IntegralType instance Classification NumericType Word8 IntegralType instance Classification NumericType Int64 IntegralType instance Classification NumericType Int32 IntegralType instance Classification NumericType Int16 IntegralType instance Classification NumericType Int8 IntegralType instance Classification NumericType Int IntegralType module Data.Random.Distribution -- | A definition of a random variable's distribution. From the -- distribution an RVar can be created, or the distribution can be -- directly sampled. RVar in particular is an instance of -- Distribution, and so can be sampled. -- -- Minimum instance definition: either rvar or sampleFrom. class Distribution d t rvar :: (Distribution d t) => d t -> RVar t sampleFrom :: (Distribution d t, RandomSource m s) => s -> d t -> m t -- | Sample a distribution using the default source of entropy for the -- monad in which the sampling occurs. sample :: (Distribution d t, MonadRandom m) => d t -> m t -- | Random variables. An RVar is a sampleable random variable. -- Because probability distributions form a monad, they are quite easy to -- work with in the standard Haskell monadic styles. For examples, see -- the source for any of the Distribution instances - they all are -- defined in terms of RVars. module Data.Random.RVar -- | An opaque type containing a "random variable" - a value which depends -- on the outcome of some random process. data RVar a -- | A random variable evenly distributed over all unsigned integers from 0 -- to 2^(8*n)-1, inclusive. nByteInteger :: Int -> RVar Integer -- | A random variable evenly distributed over all unsigned integers from 0 -- to 2^n-1, inclusive. nBitInteger :: Int -> RVar Integer instance MonadRandom RVar instance Distribution RVar a instance Applicative RVar instance Monad RVar instance Functor RVar module Data.Random.Distribution.Uniform data Uniform t Uniform :: !t -> !t -> Uniform t class (Classification NumericType t c) => UniformByClassification c t uniformByClassification :: (UniformByClassification c t) => t -> t -> RVar t uniform :: (Distribution Uniform a) => a -> a -> RVar a data StdUniform t StdUniform :: StdUniform t class (Classification NumericType t c) => StdUniformByClassification c t stdUniformByClassification :: (StdUniformByClassification c t) => RVar t stdUniform :: (Distribution StdUniform a) => RVar a realFloatUniform :: (RealFloat a) => a -> a -> RVar a boundedStdUniform :: (Distribution Uniform a, Bounded a) => RVar a boundedEnumStdUniform :: (Enum a, Bounded a) => RVar a realFloatStdUniform :: (RealFloat a) => RVar a instance (Classification NumericType t EnumType, Enum t, Bounded t) => StdUniformByClassification EnumType t instance (Classification NumericType t FractionalType, RealFloat t) => StdUniformByClassification FractionalType t instance (Classification NumericType t IntegralType, Integral t, Bounded t) => StdUniformByClassification IntegralType t instance (Classification NumericType t EnumType, Enum t) => UniformByClassification EnumType t instance (Classification NumericType t FractionalType, RealFloat t) => UniformByClassification FractionalType t instance (Classification NumericType t IntegralType, Integral t) => UniformByClassification IntegralType t instance (StdUniformByClassification c t) => Distribution StdUniform t instance (UniformByClassification c t) => Distribution Uniform t module Data.Random.Distribution.Bernoulli bernoulli :: (Distribution (Bernoulli b) a) => b -> RVar a class (Classification NumericType t c) => BernoulliByClassification c t bernoulliByClassification :: (BernoulliByClassification c t, RealFloat a) => a -> RVar t data Bernoulli b a Bernoulli :: b -> Bernoulli b a instance (BernoulliByClassification c t, RealFloat b) => Distribution (Bernoulli b) t instance (Classification NumericType t EnumType, Enum t) => BernoulliByClassification EnumType t instance (Classification NumericType t FractionalType, Num t) => BernoulliByClassification FractionalType t instance (Classification NumericType t IntegralType, Num t) => BernoulliByClassification IntegralType t module Data.Random.Distribution.Exponential data Exponential a Exp :: a -> Exponential a realFloatExponential :: (RealFloat a) => a -> RVar a exponential :: (Distribution Exponential a) => a -> RVar a instance (RealFloat a) => Distribution Exponential a module Data.Random.Distribution.Discrete discrete :: (Distribution (Discrete p) a) => [(p, a)] -> RVar a data Discrete p a Discrete :: [(p, a)] -> Discrete p a instance (Num p, Ord p, Distribution Uniform p) => Distribution (Discrete p) a module Data.Random.Distribution.Normal normalPair :: (Floating a, Distribution Uniform a) => RVar (a, a) knuthPolarNormalPair :: (Floating a, Ord a, Distribution Uniform a) => RVar (a, a) realFloatStdNormal :: (RealFloat a) => RVar a data Normal a StdNormal :: Normal a Normal :: a -> a -> Normal a stdNormal :: (Distribution Normal a) => RVar a normal :: (Distribution Normal a) => a -> a -> RVar a instance (Floating a, Distribution Uniform a) => Distribution Normal a module Data.Random.Distribution.Gamma realFloatGamma :: (RealFloat a) => a -> a -> RVar a realFloatErlang :: (Integral a, RealFloat b) => a -> RVar b gamma :: (Distribution Gamma a) => a -> a -> RVar a erlang :: (Distribution Gamma a, Integral b, Num a) => b -> a -> RVar a data Gamma a Gamma :: a -> a -> Gamma a instance (RealFloat a) => Distribution Gamma a module Data.Random.Distribution.Beta realFloatBeta :: (RealFloat a) => a -> a -> RVar a realFloatBetaFromIntegral :: (Integral a, Integral b, RealFloat c) => a -> b -> RVar c beta :: (Distribution Beta a) => a -> a -> RVar a data Beta a Beta :: a -> a -> Beta a instance (RealFloat a) => Distribution Beta a module Data.Random.Distribution.Binomial integralBinomial :: (Integral a, RealFloat b) => a -> b -> RVar a binomial :: (Distribution (Binomial b) a) => a -> b -> RVar a class (Classification NumericType t c) => BinomialByClassification c t binomialByClassification :: (BinomialByClassification c t, RealFloat a) => t -> a -> RVar t data Binomial b a Binomial :: a -> b -> Binomial b a instance (BinomialByClassification c t, RealFloat b) => Distribution (Binomial b) t instance (Classification NumericType t FractionalType, RealFrac t) => BinomialByClassification FractionalType t instance (Classification NumericType t IntegralType, Integral t) => BinomialByClassification IntegralType t module Data.Random.Distribution.Poisson integralPoisson :: (Integral a, RealFloat b) => b -> RVar a poisson :: (Distribution (Poisson b) a) => b -> RVar a data Poisson b a Poisson :: b -> Poisson b a instance (RealFloat b) => Distribution (Poisson b) Double instance (RealFloat b) => Distribution (Poisson b) Float instance (RealFloat b) => Distribution (Poisson b) Integer instance (RealFloat b) => Distribution (Poisson b) Word64 instance (RealFloat b) => Distribution (Poisson b) Word32 instance (RealFloat b) => Distribution (Poisson b) Word16 instance (RealFloat b) => Distribution (Poisson b) Word8 instance (RealFloat b) => Distribution (Poisson b) Int64 instance (RealFloat b) => Distribution (Poisson b) Int32 instance (RealFloat b) => Distribution (Poisson b) Int16 instance (RealFloat b) => Distribution (Poisson b) Int8 instance (RealFloat b) => Distribution (Poisson b) Int module Data.Random.Distribution.Triangular data Triangular a Triangular :: a -> a -> a -> Triangular a triLower :: Triangular a -> a triMid :: Triangular a -> a triUpper :: Triangular a -> a realFloatTriangular :: (RealFloat a) => a -> a -> a -> RVar a instance (Eq a) => Eq (Triangular a) instance (Show a) => Show (Triangular a) instance (RealFloat a) => Distribution Triangular a -- | Random numbers and stuff... -- -- Data.Random.Source exports the typeclasses for entropy sources, and -- Data.Random.Source.* export various instances and/or functions with -- which instances can be defined. -- -- Data.Random.Distribution exports the typeclasses for sampling -- distributions, and Data.Random.Distribution.* export various specific -- distributions. -- -- Data.Random.RVar exports the RVar type, which is a probability -- distribution monad that allows for concise definitions of random -- variables, as well as a couple handy RVars. module Data.Random