| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
Data.RVar
Description
Synopsis
- type RVar = RVarT Identity
- runRVar :: StatefulGen g m => RVar a -> g -> m a
- sampleReaderRVar :: (StatefulGen g m, MonadReader g m) => RVar a -> m a
- sampleStateRVar :: (RandomGen g, MonadState g m) => RVar a -> m a
- pureRVar :: RandomGen g => RVar a -> g -> (a, g)
- data RVarT m a
- runRVarT :: StatefulGen g m => RVarT m a -> g -> m a
- sampleReaderRVarT :: (StatefulGen g m, MonadReader g m) => RVarT m a -> m a
- sampleStateRVarT :: (RandomGen g, MonadState g m) => RVarT m a -> m a
- runRVarTWith :: forall m n g a. StatefulGen g m => (forall t. n t -> m t) -> RVarT n a -> g -> m a
- sampleReaderRVarTWith :: forall m n a g. (StatefulGen g m, MonadReader g m) => (forall t. n t -> m t) -> RVarT n a -> m a
- sampleStateRVarTWith :: forall m n a g. (RandomGen g, MonadState g m) => (forall t. n t -> m t) -> RVarT n a -> m a
- data RGen = RGen
- uniformRVarT :: Uniform a => RVarT m a
- uniformRangeRVarT :: UniformRange a => (a, a) -> RVarT m a
- data Prim a where
- PrimWord8 :: Prim Word8
- PrimWord16 :: Prim Word16
- PrimWord32 :: Prim Word32
- PrimWord64 :: Prim Word64
- PrimShortByteString :: !Int -> Prim ShortByteString
Documentation
type RVar = RVarT Identity Source #
An opaque type modeling a "random variable" - a value
which depends on the outcome of some random event. RVars
can be conveniently defined by an imperative-looking style:
normalPair = do
u <- stdUniform
t <- stdUniform
let r = sqrt (-2 * log u)
theta = (2 * pi) * t
x = r * cos theta
y = r * sin theta
return (x,y)OR by a more applicative style:
logNormal = exp <$> stdNormal
Once defined (in any style), there are several ways to sample RVars:
- Using an immutable pseudo-random number generator that has an instance for
RandomGenwithStateTmonad:
>>>import qualified Data.Random as Fu (uniform)>>>import System.Random (mkStdGen)>>>import Control.Monad.State (runState)>>>runState (sampleStateRVar (Fu.uniform 1 (100 :: Integer))) (mkStdGen 2021)(79,StdGen {unStdGen = SMGen 4687568268719557181 4805600293067301895})
- Using a mutable pseud-random number generator that has an instance for
StatefulGenwithReaderTmonad.
>>>import qualified Data.Random as Fu (uniform)>>>import System.Random.MWC (create)>>>import Control.Monad.Reader (runReaderT)>>>import qualified Data.Vector.Storable as VS>>>initialize (VS.singleton 2021) >>= runReaderT (sampleReaderRVar (uniform 1 (100 :: Integer)))8
runRVar :: StatefulGen g m => RVar a -> g -> m a Source #
"Run" an RVar - samples the random variable from the provided
source of entropy.
sampleReaderRVar :: (StatefulGen g m, MonadReader g m) => RVar a -> m a Source #
sampleRVar x is equivalent to runRVar x .StdRandom
sampleStateRVar :: (RandomGen g, MonadState g m) => RVar a -> m a Source #
pureRVar :: RandomGen g => RVar a -> g -> (a, g) Source #
Sample random variable using RandomGen generator as source of entropy
A random variable with access to operations in an underlying monad. Useful examples include any form of state for implementing random processes with hysteresis, or writer monads for implementing tracing of complicated algorithms.
For example, a simple random walk can be implemented as an RVarT IO value:
rwalkIO :: IO (RVarT IO Double)
rwalkIO d = do
lastVal <- newIORef 0
let x = do
prev <- lift (readIORef lastVal)
change <- rvarT StdNormal
let new = prev + change
lift (writeIORef lastVal new)
return new
return xTo run the random walk it must first be initialized, after which it can be sampled as usual:
do
rw <- rwalkIO
x <- sampleRVarT rw
y <- sampleRVarT rw
...The same random-walk process as above can be implemented using MTL types
as follows (using import Control.Monad.Trans as MTL):
rwalkState :: RVarT (State Double) Double
rwalkState = do
prev <- MTL.lift get
change <- rvarT StdNormal
let new = prev + change
MTL.lift (put new)
return newInvocation is straightforward (although a bit noisy) if you're used to MTL:
rwalk :: Int -> Double -> StdGen -> ([Double], StdGen)
rwalk count start gen =
flip evalState start .
flip runStateT gen .
sampleRVarTWith MTL.lift $
replicateM count rwalkStateInstances
| MonadTrans RVarT Source # | |
| MonadPrompt Prim (RVarT n) Source # | |
| StatefulGen RGen (RVarT m) Source # | |
Defined in Data.RVar Methods uniformWord32R :: Word32 -> RGen -> RVarT m Word32 # uniformWord64R :: Word64 -> RGen -> RVarT m Word64 # uniformWord8 :: RGen -> RVarT m Word8 # uniformWord16 :: RGen -> RVarT m Word16 # uniformWord32 :: RGen -> RVarT m Word32 # uniformWord64 :: RGen -> RVarT m Word64 # uniformShortByteString :: Int -> RGen -> RVarT m ShortByteString # | |
| Monad (RVarT n) Source # | |
| Functor (RVarT n) Source # | |
| Applicative (RVarT n) Source # | |
| MonadIO m => MonadIO (RVarT m) Source # | |
runRVarT :: StatefulGen g m => RVarT m a -> g -> m a Source #
sampleReaderRVarT :: (StatefulGen g m, MonadReader g m) => RVarT m a -> m a Source #
sampleStateRVarT :: (RandomGen g, MonadState g m) => RVarT m a -> m a Source #
runRVarTWith :: forall m n g a. StatefulGen g m => (forall t. n t -> m t) -> RVarT n a -> g -> m a Source #
"Runs" an RVarT, sampling the random variable it defines.
The first argument lifts the base monad into the sampling monad. This operation must obey the "monad transformer" laws:
lift . return = return lift (x >>= f) = (lift x) >>= (lift . f)
One example of a useful non-standard lifting would be one that takes
State s to another monad with a different state representation (such as
IO with the state mapped to an IORef):
embedState :: (Monad m) => m s -> (s -> m ()) -> State s a -> m a
embedState get put = \m -> do
s <- get
(res,s) <- return (runState m s)
put s
return resThe ability to lift is very important - without it, every RVar would have
to either be given access to the full capability of the monad in which it
will eventually be sampled (which, incidentally, would also have to be
monomorphic so you couldn't sample one RVar in more than one monad)
or functions manipulating RVars would have to use higher-ranked
types to enforce the same kind of isolation and polymorphism.
sampleReaderRVarTWith :: forall m n a g. (StatefulGen g m, MonadReader g m) => (forall t. n t -> m t) -> RVarT n a -> m a Source #
sampleRVarTWith lift x is equivalent to runRVarTWith lift x .StdRandom
sampleStateRVarTWith :: forall m n a g. (RandomGen g, MonadState g m) => (forall t. n t -> m t) -> RVarT n a -> m a Source #
sampleRVarTWith lift x is equivalent to runRVarTWith lift x .StdRandom
Constructors
| RGen |
Instances
| StatefulGen RGen (RVarT m) Source # | |
Defined in Data.RVar Methods uniformWord32R :: Word32 -> RGen -> RVarT m Word32 # uniformWord64R :: Word64 -> RGen -> RVarT m Word64 # uniformWord8 :: RGen -> RVarT m Word8 # uniformWord16 :: RGen -> RVarT m Word16 # uniformWord32 :: RGen -> RVarT m Word32 # uniformWord64 :: RGen -> RVarT m Word64 # uniformShortByteString :: Int -> RGen -> RVarT m ShortByteString # | |
uniformRVarT :: Uniform a => RVarT m a Source #
uniformRangeRVarT :: UniformRange a => (a, a) -> RVarT m a Source #
A Prompt GADT describing a request for a primitive random variate. Random variable
definitions will request their entropy via these prompts, and entropy sources will
satisfy those requests. This data type is needed for creating
StatefulGen instance for RVarT
Constructors
| PrimWord8 :: Prim Word8 | An unsigned byte, uniformly distributed from 0 to 0xff |
| PrimWord16 :: Prim Word16 | An unsigned 16-bit word, uniformly distributed from 0 to 0xffff |
| PrimWord32 :: Prim Word32 | An unsigned 32-bit word, uniformly distributed from 0 to 0xffffffff |
| PrimWord64 :: Prim Word64 | An unsigned 64-bit word, uniformly distributed from 0 to 0xffffffffffffffff |
| PrimShortByteString :: !Int -> Prim ShortByteString | A uniformly distributed |