random-1.2.1.3: Pseudo-random number generation

Copyright | (c) The University of Glasgow 2001
License | BSD-style (see the file LICENSE in the 'random' repository)
Maintainer | libraries@haskell.org
Stability | stable
Safe Haskell | Trustworthy
Language | Haskell2010

System.Random.Stateful

Contents

- Pure Random Generator
- Monadic Random Generator
- Usage
- Mutable pseudo-random number generator interfaces
- Monadic adapters for pure pseudo-random number generators
  - Pure adapter
  - Mutable adapter with atomic operations
  - Mutable adapter in `IO`
  - Mutable adapter in `ST`
  - Mutable adapter in `STM`
- Pseudo-random values of various types
- Generators for sequences of pseudo-random bytes
- Appendix
  - How to implement `StatefulGen`
  - Floating point number caveats
- References

Description

This library deals with the common task of pseudo-random number generation.

Synopsis

- module System.Random
- class Monad m => StatefulGen g (m :: Type -> Type) where
  - uniformWord32R :: Word32 -> g -> m Word32
  - uniformWord64R :: Word64 -> g -> m Word64
  - uniformWord8 :: g -> m Word8
  - uniformWord16 :: g -> m Word16
  - uniformWord32 :: g -> m Word32
  - uniformWord64 :: g -> m Word64
  - uniformShortByteString :: Int -> g -> m ShortByteString
- class StatefulGen (MutableGen f m) m => FrozenGen f (m :: Type -> Type) where
  - type MutableGen f (m :: Type -> Type) = (g :: Type) | g -> f
  - freezeGen :: MutableGen f m -> m f
  - thawGen :: f -> m (MutableGen f m)
- class (RandomGen r, StatefulGen g m) => RandomGenM g r (m :: Type -> Type) | g -> r where
  - applyRandomGenM :: (r -> (a, r)) -> g -> m a
- withMutableGen :: FrozenGen f m => f -> (MutableGen f m -> m a) -> m (a, f)
- withMutableGen_ :: FrozenGen f m => f -> (MutableGen f m -> m a) -> m a
- randomM :: (RandomGenM g r m, Random a) => g -> m a
- randomRM :: (RandomGenM g r m, Random a) => (a, a) -> g -> m a
- splitGenM :: RandomGenM g r m => g -> m r
- newtype StateGen g = StateGen {
  - unStateGen :: g
  }
- data StateGenM g = StateGenM
- runStateGen :: RandomGen g => g -> (StateGenM g -> State g a) -> (a, g)
- runStateGen_ :: RandomGen g => g -> (StateGenM g -> State g a) -> a
- runStateGenT :: RandomGen g => g -> (StateGenM g -> StateT g m a) -> m (a, g)
- runStateGenT_ :: (RandomGen g, Functor f) => g -> (StateGenM g -> StateT g f a) -> f a
- runStateGenST :: RandomGen g => g -> (forall s. StateGenM g -> StateT g (ST s) a) -> (a, g)
- runStateGenST_ :: RandomGen g => g -> (forall s. StateGenM g -> StateT g (ST s) a) -> a
- newtype AtomicGen g = AtomicGen {
  - unAtomicGen :: g
  }
- newtype AtomicGenM g = AtomicGenM {
  - unAtomicGenM :: IORef g
  }
- newAtomicGenM :: MonadIO m => g -> m (AtomicGenM g)
- applyAtomicGen :: MonadIO m => (g -> (a, g)) -> AtomicGenM g -> m a
- globalStdGen :: AtomicGenM StdGen
- newtype IOGen g = IOGen {
  - unIOGen :: g
  }
- newtype IOGenM g = IOGenM {
  - unIOGenM :: IORef g
  }
- newIOGenM :: MonadIO m => g -> m (IOGenM g)
- applyIOGen :: MonadIO m => (g -> (a, g)) -> IOGenM g -> m a
- newtype STGen g = STGen {
  - unSTGen :: g
  }
- newtype STGenM g s = STGenM {
  - unSTGenM :: STRef s g
  }
- newSTGenM :: g -> ST s (STGenM g s)
- applySTGen :: (g -> (a, g)) -> STGenM g s -> ST s a
- runSTGen :: RandomGen g => g -> (forall s. STGenM g s -> ST s a) -> (a, g)
- runSTGen_ :: RandomGen g => g -> (forall s. STGenM g s -> ST s a) -> a
- newtype TGen g = TGen {
  - unTGen :: g
  }
- newtype TGenM g = TGenM {
  - unTGenM :: TVar g
  }
- newTGenM :: g -> STM (TGenM g)
- newTGenMIO :: MonadIO m => g -> m (TGenM g)
- applyTGen :: (g -> (a, g)) -> TGenM g -> STM a
- class Uniform a where
  - uniformM :: StatefulGen g m => g -> m a
- uniformListM :: (StatefulGen g m, Uniform a) => Int -> g -> m [a]
- uniformViaFiniteM :: (StatefulGen g m, Generic a, GFinite (Rep a)) => g -> m a
- class UniformRange a where
  - uniformRM :: StatefulGen g m => (a, a) -> g -> m a
- genShortByteStringIO :: MonadIO m => Int -> m Word64 -> m ShortByteString
- genShortByteStringST :: Int -> ST s Word64 -> ST s ShortByteString
- uniformByteStringM :: StatefulGen g m => Int -> g -> m ByteString
- uniformDouble01M :: StatefulGen g m => g -> m Double
- uniformDoublePositive01M :: StatefulGen g m => g -> m Double
- uniformFloat01M :: StatefulGen g m => g -> m Float
- uniformFloatPositive01M :: StatefulGen g m => g -> m Float
- uniformEnumM :: (Enum a, Bounded a, StatefulGen g m) => g -> m a
- uniformEnumRM :: (Enum a, StatefulGen g m) => (a, a) -> g -> m a

# Pure Random Generator

module System.Random

# Monadic Random Generator

This module provides type classes and instances for the following concepts:

Monadic pseudo-random number generators
  `StatefulGen` is an interface to monadic pseudo-random number generators.
Monadic adapters
  `StateGenM`, `AtomicGenM`, `IOGenM`, `STGenM` and `TGenM` turn a `RandomGen` instance into a `StatefulGen` instance.
Drawing from a range
  `UniformRange` is used to generate a value of a type uniformly within a range.

  This library provides instances of `UniformRange` for many common numeric types.

Drawing from the entire domain of a type
  `Uniform` is used to generate a value of a type uniformly over all possible values of that type.

  This library provides instances of `Uniform` for many common bounded numeric types.

# Usage

In monadic code, use the relevant `Uniform` and `UniformRange` instances to generate pseudo-random values via `uniformM` and `uniformRM`, respectively.

As an example, `rollsM` generates `n` pseudo-random values of `Word` in the range `[1, 6]` in a `StatefulGen` context; given a monadic pseudo-random number generator, you can run this probabilistic computation as follows:

    >>> :{
    let rollsM :: StatefulGen g m => Int -> g -> m [Word]
        rollsM n = replicateM n . uniformRM (1, 6)
    in do
        monadicGen <- MWC.create
        rollsM 10 monadicGen :: IO [Word]
    :}
    [3,4,3,1,4,6,1,6,1,4]

Given a pure pseudo-random number generator, you can run the monadic pseudo-random number computation `rollsM` in an `IO` or `ST` context by applying a monadic adapter like `AtomicGenM`, `IOGenM` or `STGenM` (see monadic-adapters) to the pure pseudo-random number generator.

    >>> :{
    let rollsM :: StatefulGen g m => Int -> g -> m [Word]
        rollsM n = replicateM n . uniformRM (1, 6)
        pureGen = mkStdGen 42
    in
        newIOGenM pureGen >>= rollsM 10 :: IO [Word]
    :}
    [1,1,3,2,4,5,3,4,6,2]

# Mutable pseudo-random number generator interfaces

Pseudo-random number generators come in two flavours: pure and monadic.

`RandomGen`: pure pseudo-random number generators
  See System.Random module.
`StatefulGen`: monadic pseudo-random number generators
  These generators mutate their own state as they produce pseudo-random values. They generally live in `ST` or `IO` or some transformer that implements `PrimMonad`.

class Monad m => StatefulGen g (m :: Type -> Type) where Source #

`StatefulGen` is an interface to monadic pseudo-random number generators.

Since: 1.2.0

Minimal complete definition

(uniformWord32 | uniformWord64)

Methods

uniformWord32R :: Word32 -> g -> m Word32 Source #

`uniformWord32R upperBound g` generates a `Word32` that is uniformly distributed over the range `[0, upperBound]`.

Since: 1.2.0

uniformWord64R :: Word64 -> g -> m Word64 Source #

`uniformWord64R upperBound g` generates a `Word64` that is uniformly distributed over the range `[0, upperBound]`.

Since: 1.2.0

uniformWord8 :: g -> m Word8 Source #

Generates a `Word8` that is uniformly distributed over the entire `Word8` range.

The default implementation extracts a `Word8` from `uniformWord32`.

Since: 1.2.0

uniformWord16 :: g -> m Word16 Source #

Generates a `Word16` that is uniformly distributed over the entire `Word16` range.

The default implementation extracts a `Word16` from `uniformWord32`.

Since: 1.2.0

uniformWord32 :: g -> m Word32 Source #

Generates a `Word32` that is uniformly distributed over the entire `Word32` range.

The default implementation extracts a `Word32` from `uniformWord64`.

Since: 1.2.0

uniformWord64 :: g -> m Word64 Source #

Generates a `Word64` that is uniformly distributed over the entire `Word64` range.

The default implementation combines two `Word32` from `uniformWord32` into one `Word64`.

Since: 1.2.0

uniformShortByteString :: Int -> g -> m ShortByteString Source #

`uniformShortByteString n g` generates a `ShortByteString` of length `n` filled with pseudo-random bytes.

Since: 1.2.0

default uniformShortByteString :: MonadIO m => Int -> g -> m ShortByteString Source #

#### Instances

Instances details

(RandomGen g, MonadState g m) => StatefulGen (StateGenM g) m Source # |

Instance details

Defined in System.Random.Internal

Methods

uniformWord32R :: Word32 -> StateGenM g -> m Word32 Source #

uniformWord64R :: Word64 -> StateGenM g -> m Word64 Source #

uniformWord8 :: StateGenM g -> m Word8 Source #

uniformWord16 :: StateGenM g -> m Word16 Source #

uniformWord32 :: StateGenM g -> m Word32 Source #

uniformWord64 :: StateGenM g -> m Word64 Source #

uniformShortByteString :: Int -> StateGenM g -> m ShortByteString Source #

(RandomGen g, MonadIO m) => StatefulGen (AtomicGenM g) m Source # |

Instance details

Defined in System.Random.Stateful

Methods

uniformWord32R :: Word32 -> AtomicGenM g -> m Word32 Source #

uniformWord64R :: Word64 -> AtomicGenM g -> m Word64 Source #

uniformWord8 :: AtomicGenM g -> m Word8 Source #

uniformWord16 :: AtomicGenM g -> m Word16 Source #

uniformWord32 :: AtomicGenM g -> m Word32 Source #

uniformWord64 :: AtomicGenM g -> m Word64 Source #

uniformShortByteString :: Int -> AtomicGenM g -> m ShortByteString Source #

(RandomGen g, MonadIO m) => StatefulGen (IOGenM g) m Source # |

Instance details

Defined in System.Random.Stateful

Methods

uniformWord32R :: Word32 -> IOGenM g -> m Word32 Source #

uniformWord64R :: Word64 -> IOGenM g -> m Word64 Source #

uniformWord8 :: IOGenM g -> m Word8 Source #

uniformWord16 :: IOGenM g -> m Word16 Source #

uniformWord32 :: IOGenM g -> m Word32 Source #

uniformWord64 :: IOGenM g -> m Word64 Source #

uniformShortByteString :: Int -> IOGenM g -> m ShortByteString Source #

RandomGen g => StatefulGen (TGenM g) STM Source # | Since: 1.2.1

Instance details

Defined in System.Random.Stateful

Methods

uniformWord32R :: Word32 -> TGenM g -> STM Word32 Source #

uniformWord64R :: Word64 -> TGenM g -> STM Word64 Source #

uniformWord8 :: TGenM g -> STM Word8 Source #

uniformWord16 :: TGenM g -> STM Word16 Source #

uniformWord32 :: TGenM g -> STM Word32 Source #

uniformWord64 :: TGenM g -> STM Word64 Source #

uniformShortByteString :: Int -> TGenM g -> STM ShortByteString Source #

RandomGen g => StatefulGen (STGenM g s) (ST s) Source # |

Instance details

Defined in System.Random.Stateful

Methods

uniformWord32R :: Word32 -> STGenM g s -> ST s Word32 Source #

uniformWord64R :: Word64 -> STGenM g s -> ST s Word64 Source #

uniformWord8 :: STGenM g s -> ST s Word8 Source #

uniformWord16 :: STGenM g s -> ST s Word16 Source #

uniformWord32 :: STGenM g s -> ST s Word32 Source #

uniformWord64 :: STGenM g s -> ST s Word64 Source #

uniformShortByteString :: Int -> STGenM g s -> ST s ShortByteString Source #

class StatefulGen (MutableGen f m) m => FrozenGen f (m :: Type -> Type) where Source #

This class is designed for stateful pseudo-random number generators that can be saved as and restored from an immutable data type.

Since: 1.2.0

Associated Types

type MutableGen f (m :: Type -> Type) = (g :: Type) | g -> f Source #

Represents the state of the pseudo-random number generator for use with `thawGen` and `freezeGen`.

Since: 1.2.0

Methods

freezeGen :: MutableGen f m -> m f Source #

Saves the state of the pseudo-random number generator as a frozen seed.

Since: 1.2.0

thawGen :: f -> m (MutableGen f m) Source #

Restores the pseudo-random number generator from its frozen seed.

Since: 1.2.0

#### Instances

Instances details

(RandomGen g, MonadState g m) => FrozenGen (StateGen g) m Source # |

Instance details

Defined in System.Random.Internal

Associated Types

type MutableGen (StateGen g) m |
Instance details Defined in System.Random.Internal type MutableGen (StateGen g) m = StateGenM g

Methods

freezeGen :: MutableGen (StateGen g) m -> m (StateGen g) Source #

thawGen :: StateGen g -> m (MutableGen (StateGen g) m) Source #

(RandomGen g, MonadIO m) => FrozenGen (AtomicGen g) m Source # |

Instance details

Defined in System.Random.Stateful

Associated Types

type MutableGen (AtomicGen g) m |
Instance details Defined in System.Random.Stateful type MutableGen (AtomicGen g) m = AtomicGenM g

Methods

freezeGen :: MutableGen (AtomicGen g) m -> m (AtomicGen g) Source #

thawGen :: AtomicGen g -> m (MutableGen (AtomicGen g) m) Source #

(RandomGen g, MonadIO m) => FrozenGen (IOGen g) m Source # |

Instance details

Defined in System.Random.Stateful

Associated Types

type MutableGen (IOGen g) m |
Instance details Defined in System.Random.Stateful type MutableGen (IOGen g) m = IOGenM g

Methods

freezeGen :: MutableGen (IOGen g) m -> m (IOGen g) Source #

thawGen :: IOGen g -> m (MutableGen (IOGen g) m) Source #

RandomGen g => FrozenGen (TGen g) STM Source # | Since: 1.2.1

Instance details

Defined in System.Random.Stateful

Associated Types

type MutableGen (TGen g) STM |
Instance details Defined in System.Random.Stateful type MutableGen (TGen g) STM = TGenM g

Methods

freezeGen :: MutableGen (TGen g) STM -> STM (TGen g) Source #

thawGen :: TGen g -> STM (MutableGen (TGen g) STM) Source #

RandomGen g => FrozenGen (STGen g) (ST s) Source # |

Instance details

Defined in System.Random.Stateful

Associated Types

type MutableGen (STGen g) (ST s) |
Instance details Defined in System.Random.Stateful type MutableGen (STGen g) (ST s) = STGenM g s

Methods

freezeGen :: MutableGen (STGen g) (ST s) -> ST s (STGen g) Source #

thawGen :: STGen g -> ST s (MutableGen (STGen g) (ST s)) Source #

class (RandomGen r, StatefulGen g m) => RandomGenM g r (m :: Type -> Type) | g -> r where Source #

Interface to operations on `RandomGen` wrappers like `IOGenM` and `StateGenM`.

Since: 1.2.0

Methods

applyRandomGenM :: (r -> (a, r)) -> g -> m a Source #

#### Instances

Instances details

(RandomGen r, MonadState r m) => RandomGenM (StateGenM r) r m Source # |
Instance details Defined in System.Random.Stateful Methods applyRandomGenM :: (r -> (a, r)) -> StateGenM r -> m a Source #
(RandomGen r, MonadIO m) => RandomGenM (AtomicGenM r) r m Source # |
Instance details Defined in System.Random.Stateful Methods applyRandomGenM :: (r -> (a, r)) -> AtomicGenM r -> m a Source #
(RandomGen r, MonadIO m) => RandomGenM (IOGenM r) r m Source # |
Instance details Defined in System.Random.Stateful Methods applyRandomGenM :: (r -> (a, r)) -> IOGenM r -> m a Source #
RandomGen r => RandomGenM (TGenM r) r STM Source # |
Instance details Defined in System.Random.Stateful Methods applyRandomGenM :: (r -> (a, r)) -> TGenM r -> STM a Source #
RandomGen r => RandomGenM (STGenM r s) r (ST s) Source # |
Instance details Defined in System.Random.Stateful Methods applyRandomGenM :: (r -> (a, r)) -> STGenM r s -> ST s a Source #

withMutableGen :: FrozenGen f m => f -> (MutableGen f m -> m a) -> m (a, f) Source #

Runs a mutable pseudo-random number generator from its `FrozenGen` state.

#### Examples

Expand

    >>> import Data.Int (Int8)
    >>> withMutableGen (IOGen (mkStdGen 217)) (uniformListM 5) :: IO ([Int8], IOGen StdGen)
    ([-74,37,-50,-2,3],IOGen {unIOGen = StdGen {unStdGen = SMGen 4273268533320920145 15251669095119325999}})

Since: 1.2.0

withMutableGen_ :: FrozenGen f m => f -> (MutableGen f m -> m a) -> m a Source #

Same as `withMutableGen`, but only returns the generated value.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> withMutableGen_ (IOGen pureGen) (uniformRM (1 :: Int, 6 :: Int))
    4

Since: 1.2.0

randomM :: (RandomGenM g r m, Random a) => g -> m a Source #

Generates a pseudo-random value using monadic interface and `Random` instance.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> g <- newIOGenM pureGen
    >>> randomM g :: IO Double
    0.5728354935654512

Since: 1.2.0

randomRM :: (RandomGenM g r m, Random a) => (a, a) -> g -> m a Source #

Generates a pseudo-random value using monadic interface and `Random` instance.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> g <- newIOGenM pureGen
    >>> randomRM (1, 100) g :: IO Int
    52

Since: 1.2.0

splitGenM :: RandomGenM g r m => g -> m r Source #

Splits a pseudo-random number generator into two. Overwrites the mutable wrapper with one of the resulting generators and returns the other.

Since: 1.2.0

# Monadic adapters for pure pseudo-random number generators

Pure pseudo-random number generators can be used in monadic code via the adapters `StateGenM`, `AtomicGenM`, `IOGenM`, `STGenM` and `TGenM`

- `StateGenM` can be used in any state monad. With strict `StateT` there is no performance overhead compared to using the `RandomGen` instance directly. `StateGenM` is not safe to use in the presence of exceptions and concurrency.
- `AtomicGenM` is safe in the presence of exceptions and concurrency since it performs all actions atomically.
- `IOGenM` is a wrapper around an `IORef` that holds a pure generator. `IOGenM` is safe in the presence of exceptions, but not concurrency.
- `STGenM` is a wrapper around an `STRef` that holds a pure generator. `STGenM` is safe in the presence of exceptions, but not concurrency.
- `TGenM` is a wrapper around a `TVar` that holds a pure generator. `TGenM` can be used in a software transactional memory monad `STM`. It is not as performant as `AtomicGenM`, but it can provide stronger guarantees in a concurrent setting.

## Pure adapter

newtype StateGen g Source #

Wrapper for pure state gen, which acts as an immutable seed for the corresponding stateful generator `StateGenM`

Since: 1.2.0

Constructors

StateGen |

Fields

- unStateGen :: g

#### Instances

Instances details

NFData g => NFData (StateGen g) Source # |
Instance details Defined in System.Random.Internal Methods rnf :: StateGen g -> () Source #
Storable g => Storable (StateGen g) Source # |

Instance details

Defined in System.Random.Internal

Methods

sizeOf :: StateGen g -> Int Source #

alignment :: StateGen g -> Int Source #

peekElemOff :: Ptr (StateGen g) -> Int -> IO (StateGen g) Source #

pokeElemOff :: Ptr (StateGen g) -> Int -> StateGen g -> IO () Source #

peekByteOff :: Ptr b -> Int -> IO (StateGen g) Source #

pokeByteOff :: Ptr b -> Int -> StateGen g -> IO () Source #

peek :: Ptr (StateGen g) -> IO (StateGen g) Source #

poke :: Ptr (StateGen g) -> StateGen g -> IO () Source #

Show g => Show (StateGen g) Source # |
Instance details Defined in System.Random.Internal Methods showsPrec :: Int -> StateGen g -> ShowS Source # show :: StateGen g -> String Source # showList :: [StateGen g] -> ShowS Source #
Eq g => Eq (StateGen g) Source # |
Instance details Defined in System.Random.Internal Methods (==) :: StateGen g -> StateGen g -> Bool Source # (/=) :: StateGen g -> StateGen g -> Bool Source #
Ord g => Ord (StateGen g) Source # |

Instance details

Defined in System.Random.Internal

Methods

compare :: StateGen g -> StateGen g -> Ordering Source #

(<) :: StateGen g -> StateGen g -> Bool Source #

(<=) :: StateGen g -> StateGen g -> Bool Source #

(>) :: StateGen g -> StateGen g -> Bool Source #

(>=) :: StateGen g -> StateGen g -> Bool Source #

max :: StateGen g -> StateGen g -> StateGen g Source #

min :: StateGen g -> StateGen g -> StateGen g Source #

RandomGen g => RandomGen (StateGen g) Source # |

Instance details

Defined in System.Random.Internal

Methods

next :: StateGen g -> (Int, StateGen g) Source #

genWord8 :: StateGen g -> (Word8, StateGen g) Source #

genWord16 :: StateGen g -> (Word16, StateGen g) Source #

genWord32 :: StateGen g -> (Word32, StateGen g) Source #

genWord64 :: StateGen g -> (Word64, StateGen g) Source #

genWord32R :: Word32 -> StateGen g -> (Word32, StateGen g) Source #

genWord64R :: Word64 -> StateGen g -> (Word64, StateGen g) Source #

genShortByteString :: Int -> StateGen g -> (ShortByteString, StateGen g) Source #

genRange :: StateGen g -> (Int, Int) Source #

split :: StateGen g -> (StateGen g, StateGen g) Source #

(RandomGen g, MonadState g m) => FrozenGen (StateGen g) m Source # |

Instance details

Defined in System.Random.Internal

Associated Types

type MutableGen (StateGen g) m |
Instance details Defined in System.Random.Internal type MutableGen (StateGen g) m = StateGenM g

Methods

freezeGen :: MutableGen (StateGen g) m -> m (StateGen g) Source #

thawGen :: StateGen g -> m (MutableGen (StateGen g) m) Source #

type MutableGen (StateGen g) m Source # |
Instance details Defined in System.Random.Internal type MutableGen (StateGen g) m = StateGenM g

data StateGenM g Source #

Opaque data type that carries the type of a pure pseudo-random number generator.

Since: 1.2.0

Constructors

StateGenM |

#### Instances

Instances details

(RandomGen g, MonadState g m) => StatefulGen (StateGenM g) m Source # |

Instance details

Defined in System.Random.Internal

Methods

uniformWord32R :: Word32 -> StateGenM g -> m Word32 Source #

uniformWord64R :: Word64 -> StateGenM g -> m Word64 Source #

uniformWord8 :: StateGenM g -> m Word8 Source #

uniformWord16 :: StateGenM g -> m Word16 Source #

uniformWord32 :: StateGenM g -> m Word32 Source #

uniformWord64 :: StateGenM g -> m Word64 Source #

uniformShortByteString :: Int -> StateGenM g -> m ShortByteString Source #

(RandomGen r, MonadState r m) => RandomGenM (StateGenM r) r m Source # |
Instance details Defined in System.Random.Stateful Methods applyRandomGenM :: (r -> (a, r)) -> StateGenM r -> m a Source #

runStateGen :: RandomGen g => g -> (StateGenM g -> State g a) -> (a, g) Source #

Runs a monadic generating action in the `State` monad using a pure pseudo-random number generator.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> runStateGen pureGen randomM :: (Int, StdGen)
    (7879794327570578227,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})

Since: 1.2.0

runStateGen_ :: RandomGen g => g -> (StateGenM g -> State g a) -> a Source #

Runs a monadic generating action in the `State` monad using a pure pseudo-random number generator. Returns only the resulting pseudo-random value.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> runStateGen_ pureGen randomM :: Int
    7879794327570578227

Since: 1.2.0

runStateGenT :: RandomGen g => g -> (StateGenM g -> StateT g m a) -> m (a, g) Source #

Runs a monadic generating action in the `StateT` monad using a pure pseudo-random number generator.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> runStateGenT pureGen randomM :: IO (Int, StdGen)
    (7879794327570578227,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})

Since: 1.2.0

runStateGenT_ :: (RandomGen g, Functor f) => g -> (StateGenM g -> StateT g f a) -> f a Source #

Runs a monadic generating action in the `StateT` monad using a pure pseudo-random number generator. Returns only the resulting pseudo-random value.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> runStateGenT_ pureGen randomM :: IO Int
    7879794327570578227

Since: 1.2.1

runStateGenST :: RandomGen g => g -> (forall s. StateGenM g -> StateT g (ST s) a) -> (a, g) Source #

Runs a monadic generating action in the `ST` monad using a pure pseudo-random number generator.

Since: 1.2.0

runStateGenST_ :: RandomGen g => g -> (forall s. StateGenM g -> StateT g (ST s) a) -> a Source #

Runs a monadic generating action in the `ST` monad using a pure pseudo-random number generator. Same as `runStateGenST`, but discards the resulting generator.

Since: 1.2.1

## Mutable adapter with atomic operations

newtype AtomicGen g Source #

Frozen version of mutable `AtomicGenM` generator

Since: 1.2.0

Constructors

AtomicGen |

Fields

- unAtomicGen :: g

#### Instances

Instances details

NFData g => NFData (AtomicGen g) Source # |
Instance details Defined in System.Random.Stateful Methods rnf :: AtomicGen g -> () Source #
Storable g => Storable (AtomicGen g) Source # |

Instance details

Defined in System.Random.Stateful

Methods

sizeOf :: AtomicGen g -> Int Source #

alignment :: AtomicGen g -> Int Source #

peekElemOff :: Ptr (AtomicGen g) -> Int -> IO (AtomicGen g) Source #

pokeElemOff :: Ptr (AtomicGen g) -> Int -> AtomicGen g -> IO () Source #

peekByteOff :: Ptr b -> Int -> IO (AtomicGen g) Source #

pokeByteOff :: Ptr b -> Int -> AtomicGen g -> IO () Source #

peek :: Ptr (AtomicGen g) -> IO (AtomicGen g) Source #

poke :: Ptr (AtomicGen g) -> AtomicGen g -> IO () Source #

Show g => Show (AtomicGen g) Source # |
Instance details Defined in System.Random.Stateful Methods showsPrec :: Int -> AtomicGen g -> ShowS Source # show :: AtomicGen g -> String Source # showList :: [AtomicGen g] -> ShowS Source #
Eq g => Eq (AtomicGen g) Source # |
Instance details Defined in System.Random.Stateful Methods (==) :: AtomicGen g -> AtomicGen g -> Bool Source # (/=) :: AtomicGen g -> AtomicGen g -> Bool Source #
Ord g => Ord (AtomicGen g) Source # |

Instance details

Defined in System.Random.Stateful

Methods

compare :: AtomicGen g -> AtomicGen g -> Ordering Source #

(<) :: AtomicGen g -> AtomicGen g -> Bool Source #

(<=) :: AtomicGen g -> AtomicGen g -> Bool Source #

(>) :: AtomicGen g -> AtomicGen g -> Bool Source #

(>=) :: AtomicGen g -> AtomicGen g -> Bool Source #

max :: AtomicGen g -> AtomicGen g -> AtomicGen g Source #

min :: AtomicGen g -> AtomicGen g -> AtomicGen g Source #

RandomGen g => RandomGen (AtomicGen g) Source # |

Instance details

Defined in System.Random.Stateful

Methods

next :: AtomicGen g -> (Int, AtomicGen g) Source #

genWord8 :: AtomicGen g -> (Word8, AtomicGen g) Source #

genWord16 :: AtomicGen g -> (Word16, AtomicGen g) Source #

genWord32 :: AtomicGen g -> (Word32, AtomicGen g) Source #

genWord64 :: AtomicGen g -> (Word64, AtomicGen g) Source #

genWord32R :: Word32 -> AtomicGen g -> (Word32, AtomicGen g) Source #

genWord64R :: Word64 -> AtomicGen g -> (Word64, AtomicGen g) Source #

genShortByteString :: Int -> AtomicGen g -> (ShortByteString, AtomicGen g) Source #

genRange :: AtomicGen g -> (Int, Int) Source #

split :: AtomicGen g -> (AtomicGen g, AtomicGen g) Source #

(RandomGen g, MonadIO m) => FrozenGen (AtomicGen g) m Source # |

Instance details

Defined in System.Random.Stateful

Associated Types

type MutableGen (AtomicGen g) m |
Instance details Defined in System.Random.Stateful type MutableGen (AtomicGen g) m = AtomicGenM g

Methods

freezeGen :: MutableGen (AtomicGen g) m -> m (AtomicGen g) Source #

thawGen :: AtomicGen g -> m (MutableGen (AtomicGen g) m) Source #

type MutableGen (AtomicGen g) m Source # |
Instance details Defined in System.Random.Stateful type MutableGen (AtomicGen g) m = AtomicGenM g

newtype AtomicGenM g Source #

Wraps an `IORef` that holds a pure pseudo-random number generator. All operations are performed atomically.

- `AtomicGenM` is safe in the presence of exceptions and concurrency.
- `AtomicGenM` is the slowest of the monadic adapters due to the overhead of its atomic operations.

Since: 1.2.0

Constructors

AtomicGenM |

Fields

- unAtomicGenM :: IORef g

#### Instances

Instances details

(RandomGen g, MonadIO m) => StatefulGen (AtomicGenM g) m Source # |

Instance details

Defined in System.Random.Stateful

Methods

uniformWord32R :: Word32 -> AtomicGenM g -> m Word32 Source #

uniformWord64R :: Word64 -> AtomicGenM g -> m Word64 Source #

uniformWord8 :: AtomicGenM g -> m Word8 Source #

uniformWord16 :: AtomicGenM g -> m Word16 Source #

uniformWord32 :: AtomicGenM g -> m Word32 Source #

uniformWord64 :: AtomicGenM g -> m Word64 Source #

uniformShortByteString :: Int -> AtomicGenM g -> m ShortByteString Source #

(RandomGen r, MonadIO m) => RandomGenM (AtomicGenM r) r m Source # |
Instance details Defined in System.Random.Stateful Methods applyRandomGenM :: (r -> (a, r)) -> AtomicGenM r -> m a Source #

newAtomicGenM :: MonadIO m => g -> m (AtomicGenM g) Source #

Creates a new `AtomicGenM`.

Since: 1.2.0

applyAtomicGen :: MonadIO m => (g -> (a, g)) -> AtomicGenM g -> m a Source #

Atomically applies a pure operation to the wrapped pseudo-random number generator.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> g <- newAtomicGenM pureGen
    >>> applyAtomicGen random g :: IO Int
    7879794327570578227

Since: 1.2.0

globalStdGen :: AtomicGenM StdGen Source #

Global mutable standard pseudo-random number generator. This is the same generator that was historically used by `randomIO` and `randomRIO` functions.

    >>> replicateM 10 (uniformRM ('a', 'z') globalStdGen)
    "tdzxhyfvgr"

Since: 1.2.1

## Mutable adapter in `IO`

newtype IOGen g Source #

Frozen version of mutable `IOGenM` generator

Since: 1.2.0

Constructors

IOGen |

Fields

- unIOGen :: g

#### Instances

Instances details

NFData g => NFData (IOGen g) Source # |
Instance details Defined in System.Random.Stateful Methods rnf :: IOGen g -> () Source #
Storable g => Storable (IOGen g) Source # |

Instance details

Defined in System.Random.Stateful

Methods

sizeOf :: IOGen g -> Int Source #

alignment :: IOGen g -> Int Source #

peekElemOff :: Ptr (IOGen g) -> Int -> IO (IOGen g) Source #

pokeElemOff :: Ptr (IOGen g) -> Int -> IOGen g -> IO () Source #

peekByteOff :: Ptr b -> Int -> IO (IOGen g) Source #

pokeByteOff :: Ptr b -> Int -> IOGen g -> IO () Source #

peek :: Ptr (IOGen g) -> IO (IOGen g) Source #

poke :: Ptr (IOGen g) -> IOGen g -> IO () Source #

Show g => Show (IOGen g) Source # |
Instance details Defined in System.Random.Stateful Methods showsPrec :: Int -> IOGen g -> ShowS Source # show :: IOGen g -> String Source # showList :: [IOGen g] -> ShowS Source #
Eq g => Eq (IOGen g) Source # |
Instance details Defined in System.Random.Stateful Methods (==) :: IOGen g -> IOGen g -> Bool Source # (/=) :: IOGen g -> IOGen g -> Bool Source #
Ord g => Ord (IOGen g) Source # |
Instance details Defined in System.Random.Stateful Methods compare :: IOGen g -> IOGen g -> Ordering Source # (<) :: IOGen g -> IOGen g -> Bool Source # (<=) :: IOGen g -> IOGen g -> Bool Source # (>) :: IOGen g -> IOGen g -> Bool Source # (>=) :: IOGen g -> IOGen g -> Bool Source # max :: IOGen g -> IOGen g -> IOGen g Source # min :: IOGen g -> IOGen g -> IOGen g Source #
RandomGen g => RandomGen (IOGen g) Source # |

Instance details

Defined in System.Random.Stateful

Methods

next :: IOGen g -> (Int, IOGen g) Source #

genWord8 :: IOGen g -> (Word8, IOGen g) Source #

genWord16 :: IOGen g -> (Word16, IOGen g) Source #

genWord32 :: IOGen g -> (Word32, IOGen g) Source #

genWord64 :: IOGen g -> (Word64, IOGen g) Source #

genWord32R :: Word32 -> IOGen g -> (Word32, IOGen g) Source #

genWord64R :: Word64 -> IOGen g -> (Word64, IOGen g) Source #

genShortByteString :: Int -> IOGen g -> (ShortByteString, IOGen g) Source #

genRange :: IOGen g -> (Int, Int) Source #

split :: IOGen g -> (IOGen g, IOGen g) Source #

(RandomGen g, MonadIO m) => FrozenGen (IOGen g) m Source # |

Instance details

Defined in System.Random.Stateful

Associated Types

type MutableGen (IOGen g) m |
Instance details Defined in System.Random.Stateful type MutableGen (IOGen g) m = IOGenM g

Methods

freezeGen :: MutableGen (IOGen g) m -> m (IOGen g) Source #

thawGen :: IOGen g -> m (MutableGen (IOGen g) m) Source #

type MutableGen (IOGen g) m Source # |
Instance details Defined in System.Random.Stateful type MutableGen (IOGen g) m = IOGenM g

newtype IOGenM g Source #

Wraps an `IORef` that holds a pure pseudo-random number generator.

- `IOGenM` is safe in the presence of exceptions, but not concurrency.
- `IOGenM` is slower than `StateGenM` due to the extra pointer indirection.
- `IOGenM` is faster than `AtomicGenM` since the `IORef` operations used by `IOGenM` are not atomic.

An example use case is writing pseudo-random bytes into a file:

    >>> import UnliftIO.Temporary (withSystemTempFile)
    >>> import Data.ByteString (hPutStr)
    >>> let ioGen g = withSystemTempFile "foo.bin" $ \_ h -> uniformRM (0, 100) g >>= flip uniformByteStringM g >>= hPutStr h

and then run it:

    >>> newIOGenM (mkStdGen 1729) >>= ioGen

Since: 1.2.0

Constructors

IOGenM |

Fields

- unIOGenM :: IORef g

#### Instances

Instances details

(RandomGen g, MonadIO m) => StatefulGen (IOGenM g) m Source # |

Instance details

Defined in System.Random.Stateful

Methods

uniformWord32R :: Word32 -> IOGenM g -> m Word32 Source #

uniformWord64R :: Word64 -> IOGenM g -> m Word64 Source #

uniformWord8 :: IOGenM g -> m Word8 Source #

uniformWord16 :: IOGenM g -> m Word16 Source #

uniformWord32 :: IOGenM g -> m Word32 Source #

uniformWord64 :: IOGenM g -> m Word64 Source #

uniformShortByteString :: Int -> IOGenM g -> m ShortByteString Source #

(RandomGen r, MonadIO m) => RandomGenM (IOGenM r) r m Source # |
Instance details Defined in System.Random.Stateful Methods applyRandomGenM :: (r -> (a, r)) -> IOGenM r -> m a Source #

newIOGenM :: MonadIO m => g -> m (IOGenM g) Source #

Creates a new `IOGenM`.

Since: 1.2.0

applyIOGen :: MonadIO m => (g -> (a, g)) -> IOGenM g -> m a Source #

Applies a pure operation to the wrapped pseudo-random number generator.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> g <- newIOGenM pureGen
    >>> applyIOGen random g :: IO Int
    7879794327570578227

Since: 1.2.0

## Mutable adapter in `ST`

newtype STGen g Source #

Frozen version of mutable `STGenM` generator

Since: 1.2.0

Constructors

STGen |

Fields

- unSTGen :: g

#### Instances

Instances details

NFData g => NFData (STGen g) Source # |
Instance details Defined in System.Random.Stateful Methods rnf :: STGen g -> () Source #
Storable g => Storable (STGen g) Source # |

Instance details

Defined in System.Random.Stateful

Methods

sizeOf :: STGen g -> Int Source #

alignment :: STGen g -> Int Source #

peekElemOff :: Ptr (STGen g) -> Int -> IO (STGen g) Source #

pokeElemOff :: Ptr (STGen g) -> Int -> STGen g -> IO () Source #

peekByteOff :: Ptr b -> Int -> IO (STGen g) Source #

pokeByteOff :: Ptr b -> Int -> STGen g -> IO () Source #

peek :: Ptr (STGen g) -> IO (STGen g) Source #

poke :: Ptr (STGen g) -> STGen g -> IO () Source #

Show g => Show (STGen g) Source # |
Instance details Defined in System.Random.Stateful Methods showsPrec :: Int -> STGen g -> ShowS Source # show :: STGen g -> String Source # showList :: [STGen g] -> ShowS Source #
Eq g => Eq (STGen g) Source # |
Instance details Defined in System.Random.Stateful Methods (==) :: STGen g -> STGen g -> Bool Source # (/=) :: STGen g -> STGen g -> Bool Source #
Ord g => Ord (STGen g) Source # |
Instance details Defined in System.Random.Stateful Methods compare :: STGen g -> STGen g -> Ordering Source # (<) :: STGen g -> STGen g -> Bool Source # (<=) :: STGen g -> STGen g -> Bool Source # (>) :: STGen g -> STGen g -> Bool Source # (>=) :: STGen g -> STGen g -> Bool Source # max :: STGen g -> STGen g -> STGen g Source # min :: STGen g -> STGen g -> STGen g Source #
RandomGen g => RandomGen (STGen g) Source # |

Instance details

Defined in System.Random.Stateful

Methods

next :: STGen g -> (Int, STGen g) Source #

genWord8 :: STGen g -> (Word8, STGen g) Source #

genWord16 :: STGen g -> (Word16, STGen g) Source #

genWord32 :: STGen g -> (Word32, STGen g) Source #

genWord64 :: STGen g -> (Word64, STGen g) Source #

genWord32R :: Word32 -> STGen g -> (Word32, STGen g) Source #

genWord64R :: Word64 -> STGen g -> (Word64, STGen g) Source #

genShortByteString :: Int -> STGen g -> (ShortByteString, STGen g) Source #

genRange :: STGen g -> (Int, Int) Source #

split :: STGen g -> (STGen g, STGen g) Source #

RandomGen g => FrozenGen (STGen g) (ST s) Source # |

Instance details

Defined in System.Random.Stateful

Associated Types

type MutableGen (STGen g) (ST s) |
Instance details Defined in System.Random.Stateful type MutableGen (STGen g) (ST s) = STGenM g s

Methods

freezeGen :: MutableGen (STGen g) (ST s) -> ST s (STGen g) Source #

thawGen :: STGen g -> ST s (MutableGen (STGen g) (ST s)) Source #

type MutableGen (STGen g) (ST s) Source # |
Instance details Defined in System.Random.Stateful type MutableGen (STGen g) (ST s) = STGenM g s

newtype STGenM g s Source #

Wraps an `STRef` that holds a pure pseudo-random number generator.

- `STGenM` is safe in the presence of exceptions, but not concurrency.
- `STGenM` is slower than `StateGenM` due to the extra pointer indirection.

Since: 1.2.0

Constructors

STGenM |

Fields

- unSTGenM :: STRef s g

#### Instances

Instances details

RandomGen r => RandomGenM (STGenM r s) r (ST s) Source # |
Instance details Defined in System.Random.Stateful Methods applyRandomGenM :: (r -> (a, r)) -> STGenM r s -> ST s a Source #
RandomGen g => StatefulGen (STGenM g s) (ST s) Source # |

Instance details

Defined in System.Random.Stateful

Methods

uniformWord32R :: Word32 -> STGenM g s -> ST s Word32 Source #

uniformWord64R :: Word64 -> STGenM g s -> ST s Word64 Source #

uniformWord8 :: STGenM g s -> ST s Word8 Source #

uniformWord16 :: STGenM g s -> ST s Word16 Source #

uniformWord32 :: STGenM g s -> ST s Word32 Source #

uniformWord64 :: STGenM g s -> ST s Word64 Source #

uniformShortByteString :: Int -> STGenM g s -> ST s ShortByteString Source #

newSTGenM :: g -> ST s (STGenM g s) Source #

Creates a new `STGenM`.

Since: 1.2.0

applySTGen :: (g -> (a, g)) -> STGenM g s -> ST s a Source #

Applies a pure operation to the wrapped pseudo-random number generator.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> (runSTGen pureGen (\g -> applySTGen random g)) :: (Int, StdGen)
    (7879794327570578227,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})

Since: 1.2.0

runSTGen :: RandomGen g => g -> (forall s. STGenM g s -> ST s a) -> (a, g) Source #

Runs a monadic generating action in the `ST` monad using a pure pseudo-random number generator.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> (runSTGen pureGen (\g -> applySTGen random g)) :: (Int, StdGen)
    (7879794327570578227,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})

Since: 1.2.0

runSTGen_ :: RandomGen g => g -> (forall s. STGenM g s -> ST s a) -> a Source #

Runs a monadic generating action in the `ST` monad using a pure pseudo-random number generator. Returns only the resulting pseudo-random value.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> (runSTGen_ pureGen (\g -> applySTGen random g)) :: Int
    7879794327570578227

Since: 1.2.0

## Mutable adapter in `STM`

newtype TGen g Source #

Frozen version of mutable `TGenM` generator

Since: 1.2.1

Constructors

TGen |

Fields

- unTGen :: g

#### Instances

Instances details

NFData g => NFData (TGen g) Source # |
Instance details Defined in System.Random.Stateful Methods rnf :: TGen g -> () Source #
Storable g => Storable (TGen g) Source # |

Instance details

Defined in System.Random.Stateful

Methods

sizeOf :: TGen g -> Int Source #

alignment :: TGen g -> Int Source #

peekElemOff :: Ptr (TGen g) -> Int -> IO (TGen g) Source #

pokeElemOff :: Ptr (TGen g) -> Int -> TGen g -> IO () Source #

peekByteOff :: Ptr b -> Int -> IO (TGen g) Source #

pokeByteOff :: Ptr b -> Int -> TGen g -> IO () Source #

peek :: Ptr (TGen g) -> IO (TGen g) Source #

poke :: Ptr (TGen g) -> TGen g -> IO () Source #

Show g => Show (TGen g) Source # |
Instance details Defined in System.Random.Stateful Methods showsPrec :: Int -> TGen g -> ShowS Source # show :: TGen g -> String Source # showList :: [TGen g] -> ShowS Source #
Eq g => Eq (TGen g) Source # |
Instance details Defined in System.Random.Stateful Methods (==) :: TGen g -> TGen g -> Bool Source # (/=) :: TGen g -> TGen g -> Bool Source #
Ord g => Ord (TGen g) Source # |
Instance details Defined in System.Random.Stateful Methods compare :: TGen g -> TGen g -> Ordering Source # (<) :: TGen g -> TGen g -> Bool Source # (<=) :: TGen g -> TGen g -> Bool Source # (>) :: TGen g -> TGen g -> Bool Source # (>=) :: TGen g -> TGen g -> Bool Source # max :: TGen g -> TGen g -> TGen g Source # min :: TGen g -> TGen g -> TGen g Source #
RandomGen g => RandomGen (TGen g) Source # |

Instance details

Defined in System.Random.Stateful

Methods

next :: TGen g -> (Int, TGen g) Source #

genWord8 :: TGen g -> (Word8, TGen g) Source #

genWord16 :: TGen g -> (Word16, TGen g) Source #

genWord32 :: TGen g -> (Word32, TGen g) Source #

genWord64 :: TGen g -> (Word64, TGen g) Source #

genWord32R :: Word32 -> TGen g -> (Word32, TGen g) Source #

genWord64R :: Word64 -> TGen g -> (Word64, TGen g) Source #

genShortByteString :: Int -> TGen g -> (ShortByteString, TGen g) Source #

genRange :: TGen g -> (Int, Int) Source #

split :: TGen g -> (TGen g, TGen g) Source #

RandomGen g => FrozenGen (TGen g) STM Source # | Since: 1.2.1

Instance details

Defined in System.Random.Stateful

Associated Types

type MutableGen (TGen g) STM |
Instance details Defined in System.Random.Stateful type MutableGen (TGen g) STM = TGenM g

Methods

freezeGen :: MutableGen (TGen g) STM -> STM (TGen g) Source #

thawGen :: TGen g -> STM (MutableGen (TGen g) STM) Source #

type MutableGen (TGen g) STM Source # |
Instance details Defined in System.Random.Stateful type MutableGen (TGen g) STM = TGenM g

newtype TGenM g Source #

Wraps a `TVar` that holds a pure pseudo-random number generator.

Since: 1.2.1

Constructors

TGenM |

Fields

- unTGenM :: TVar g

#### Instances

Instances details

RandomGen g => StatefulGen (TGenM g) STM Source # | Since: 1.2.1

Instance details

Defined in System.Random.Stateful

Methods

uniformWord32R :: Word32 -> TGenM g -> STM Word32 Source #

uniformWord64R :: Word64 -> TGenM g -> STM Word64 Source #

uniformWord8 :: TGenM g -> STM Word8 Source #

uniformWord16 :: TGenM g -> STM Word16 Source #

uniformWord32 :: TGenM g -> STM Word32 Source #

uniformWord64 :: TGenM g -> STM Word64 Source #

uniformShortByteString :: Int -> TGenM g -> STM ShortByteString Source #

RandomGen r => RandomGenM (TGenM r) r STM Source # |
Instance details Defined in System.Random.Stateful Methods applyRandomGenM :: (r -> (a, r)) -> TGenM r -> STM a Source #

newTGenM :: g -> STM (TGenM g) Source #

Creates a new `TGenM` in `STM`.

Since: 1.2.1

newTGenMIO :: MonadIO m => g -> m (TGenM g) Source #

Creates a new `TGenM` in `IO`.

Since: 1.2.1

applyTGen :: (g -> (a, g)) -> TGenM g -> STM a Source #

Applies a pure operation to the wrapped pseudo-random number generator.

#### Examples

Expand

    >>> import Control.Concurrent.STM
    >>> import System.Random.Stateful
    >>> import Data.Int (Int32)
    >>> let pureGen = mkStdGen 137
    >>> stmGen <- newTGenMIO pureGen
    >>> atomically $ applyTGen uniform stmGen :: IO Int32
    637238067

Since: 1.2.1

# Pseudo-random values of various types

This library provides two type classes to generate pseudo-random values:

- `UniformRange` is used to generate a value of a type uniformly within a range.
- `Uniform` is used to generate a value of a type uniformly over all possible values of that type.

Types may have instances for both or just one of `UniformRange` and `Uniform`. A few examples illustrate this:

- `Int`, `Word16` and `Bool` are instances of both `UniformRange` and `Uniform`.
- `Integer`, `Float` and `Double` each have an instance for `UniformRange` but no `Uniform` instance.
- A hypothetical type `Radian` representing angles by taking values in the range `[0, 2π)` has a trivial `Uniform` instance, but no `UniformRange` instance: the problem is that two given `Radian` values always span two ranges, one clockwise and one anti-clockwise.
- It is trivial to construct a `Uniform (a, b)` instance given `Uniform a` and `Uniform b` (and this library provides this tuple instance).
- On the other hand, there is no correct way to construct a `UniformRange (a, b)` instance based on just `UniformRange a` and `UniformRange b`.

class Uniform a where Source #

The class of types for which a uniformly distributed value can be drawn from all possible values of the type.

Since: 1.2.0

Minimal complete definition

Nothing

Methods

uniformM :: StatefulGen g m => g -> m a Source #

Generates a value uniformly distributed over all possible values of that type.

There is a default implementation via `Generic`:

    >>> :set -XDeriveGeneric -XDeriveAnyClass
    >>> import GHC.Generics (Generic)
    >>> import System.Random.Stateful
    >>> data MyBool = MyTrue | MyFalse deriving (Show, Generic, Finite, Uniform)
    >>> data Action = Code MyBool | Eat (Maybe Bool) | Sleep deriving (Show, Generic, Finite, Uniform)
    >>> gen <- newIOGenM (mkStdGen 42)
    >>> uniformListM 10 gen :: IO [Action]
    [Code MyTrue,Code MyTrue,Eat Nothing,Code MyFalse,Eat (Just False),Eat (Just True),Eat Nothing,Eat (Just False),Sleep,Code MyFalse]

Since: 1.2.0

default uniformM :: (StatefulGen g m, Generic a, GUniform (Rep a)) => g -> m a Source #

#### Instances

Instances details

Uniform CBool Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CBool Source #
Uniform CChar Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CChar Source #
Uniform CInt Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CInt Source #
Uniform CIntMax Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CIntMax Source #
Uniform CIntPtr Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CIntPtr Source #
Uniform CLLong Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CLLong Source #
Uniform CLong Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CLong Source #
Uniform CPtrdiff Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CPtrdiff Source #
Uniform CSChar Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CSChar Source #
Uniform CShort Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CShort Source #
Uniform CSigAtomic Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CSigAtomic Source #
Uniform CSize Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CSize Source #
Uniform CUChar Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CUChar Source #
Uniform CUInt Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CUInt Source #
Uniform CUIntMax Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CUIntMax Source #
Uniform CUIntPtr Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CUIntPtr Source #
Uniform CULLong Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CULLong Source #
Uniform CULong Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CULong Source #
Uniform CUShort Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CUShort Source #
Uniform CWchar Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m CWchar Source #
Uniform Int16 Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Int16 Source #
Uniform Int32 Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Int32 Source #
Uniform Int64 Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Int64 Source #
Uniform Int8 Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Int8 Source #
Uniform Word16 Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Word16 Source #
Uniform Word32 Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Word32 Source #
Uniform Word64 Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Word64 Source #
Uniform Word8 Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Word8 Source #
Uniform () Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m () Source #
Uniform Bool Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Bool Source #
Uniform Char Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Char Source #
Uniform Int Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Int Source #
Uniform Word Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m Word Source #
(Uniform a, Uniform b) => Uniform (a, b) Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m (a, b) Source #
(Uniform a, Uniform b, Uniform c) => Uniform (a, b, c) Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m (a, b, c) Source #
(Uniform a, Uniform b, Uniform c, Uniform d) => Uniform (a, b, c, d) Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m (a, b, c, d) Source #
(Uniform a, Uniform b, Uniform c, Uniform d, Uniform e) => Uniform (a, b, c, d, e) Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m (a, b, c, d, e) Source #
(Uniform a, Uniform b, Uniform c, Uniform d, Uniform e, Uniform f) => Uniform (a, b, c, d, e, f) Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g m => g -> m (a, b, c, d, e, f) Source #
(Uniform a, Uniform b, Uniform c, Uniform d, Uniform e, Uniform f, Uniform g) => Uniform (a, b, c, d, e, f, g) Source # |
Instance details Defined in System.Random.Internal Methods uniformM :: StatefulGen g0 m => g0 -> m (a, b, c, d, e, f, g) Source #

uniformListM :: (StatefulGen g m, Uniform a) => Int -> g -> m [a] Source #

Generates a list of pseudo-random values.

#### Examples

Expand

    >>> import System.Random.Stateful
    >>> let pureGen = mkStdGen 137
    >>> g <- newIOGenM pureGen
    >>> uniformListM 10 g :: IO [Bool]
    [True,True,True,True,False,True,True,False,False,False]

Since: 1.2.0

uniformViaFiniteM :: (StatefulGen g m, Generic a, GFinite (Rep a)) => g -> m a Source #

A definition of `Uniform` for `Finite` types. If your data has several fields of sub-`Word` cardinality, this instance may be more efficient than one, derived via `Generic` and `GUniform`.

    >>> :set -XDeriveGeneric -XDeriveAnyClass
    >>> import GHC.Generics (Generic)
    >>> import System.Random.Stateful
    >>> data Triple = Triple Word8 Word8 Word8 deriving (Show, Generic, Finite)
    >>> instance Uniform Triple where uniformM = uniformViaFiniteM
    >>> gen <- newIOGenM (mkStdGen 42)
    >>> uniformListM 5 gen :: IO [Triple]
    [Triple 60 226 48,Triple 234 194 151,Triple 112 96 95,Triple 51 251 15,Triple 6 0 208]

class UniformRange a where Source #

The class of types for which a uniformly distributed value can be drawn from a range.

Since: 1.2.0

Methods

uniformRM :: StatefulGen g m => (a, a) -> g -> m a Source #

Generates a value uniformly distributed over the provided range, which is interpreted as inclusive in the lower and upper bound.

- `uniformRM (1 :: Int, 4 :: Int)` generates values uniformly from the set \(\{1,2,3,4\}\)
- `uniformRM (1 :: Float, 4 :: Float)` generates values uniformly from the set \(\{x\;|\;1 \le x \le 4\}\)

The following law should hold to make the function always defined:

    uniformRM (a, b) = uniformRM (b, a)

Since: 1.2.0

#### Instances

Instances details

UniformRange CBool Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CBool, CBool) -> g -> m CBool Source #
UniformRange CChar Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CChar, CChar) -> g -> m CChar Source #
UniformRange CDouble Source # | See Floating point number caveats.
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CDouble, CDouble) -> g -> m CDouble Source #
UniformRange CFloat Source # | See Floating point number caveats.
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CFloat, CFloat) -> g -> m CFloat Source #
UniformRange CInt Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CInt, CInt) -> g -> m CInt Source #
UniformRange CIntMax Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CIntMax, CIntMax) -> g -> m CIntMax Source #
UniformRange CIntPtr Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CIntPtr, CIntPtr) -> g -> m CIntPtr Source #
UniformRange CLLong Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CLLong, CLLong) -> g -> m CLLong Source #
UniformRange CLong Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CLong, CLong) -> g -> m CLong Source #
UniformRange CPtrdiff Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CPtrdiff, CPtrdiff) -> g -> m CPtrdiff Source #
UniformRange CSChar Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CSChar, CSChar) -> g -> m CSChar Source #
UniformRange CShort Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CShort, CShort) -> g -> m CShort Source #
UniformRange CSigAtomic Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CSigAtomic, CSigAtomic) -> g -> m CSigAtomic Source #
UniformRange CSize Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CSize, CSize) -> g -> m CSize Source #
UniformRange CUChar Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CUChar, CUChar) -> g -> m CUChar Source #
UniformRange CUInt Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CUInt, CUInt) -> g -> m CUInt Source #
UniformRange CUIntMax Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CUIntMax, CUIntMax) -> g -> m CUIntMax Source #
UniformRange CUIntPtr Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CUIntPtr, CUIntPtr) -> g -> m CUIntPtr Source #
UniformRange CULLong Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CULLong, CULLong) -> g -> m CULLong Source #
UniformRange CULong Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CULong, CULong) -> g -> m CULong Source #
UniformRange CUShort Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CUShort, CUShort) -> g -> m CUShort Source #
UniformRange CWchar Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (CWchar, CWchar) -> g -> m CWchar Source #
UniformRange Int16 Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Int16, Int16) -> g -> m Int16 Source #
UniformRange Int32 Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Int32, Int32) -> g -> m Int32 Source #
UniformRange Int64 Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Int64, Int64) -> g -> m Int64 Source #
UniformRange Int8 Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Int8, Int8) -> g -> m Int8 Source #
UniformRange Word16 Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Word16, Word16) -> g -> m Word16 Source #
UniformRange Word32 Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Word32, Word32) -> g -> m Word32 Source #
UniformRange Word64 Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Word64, Word64) -> g -> m Word64 Source #
UniformRange Word8 Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Word8, Word8) -> g -> m Word8 Source #
UniformRange Integer Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Integer, Integer) -> g -> m Integer Source #
UniformRange Natural Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Natural, Natural) -> g -> m Natural Source #
UniformRange () Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => ((), ()) -> g -> m () Source #
UniformRange Bool Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Bool, Bool) -> g -> m Bool Source #
UniformRange Char Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Char, Char) -> g -> m Char Source #
UniformRange Double Source # | See Floating point number caveats.
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Double, Double) -> g -> m Double Source #
UniformRange Float Source # | See Floating point number caveats.
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Float, Float) -> g -> m Float Source #
UniformRange Int Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Int, Int) -> g -> m Int Source #
UniformRange Word Source # |
Instance details Defined in System.Random.Internal Methods uniformRM :: StatefulGen g m => (Word, Word) -> g -> m Word Source #

# Generators for sequences of pseudo-random bytes

genShortByteStringIO Source #

Arguments

:: MonadIO m |
=> Int | Number of bytes to generate
-> m Word64 | IO action that can generate 8 random bytes at a time
-> m ShortByteString |

Efficiently generates a sequence of pseudo-random bytes in a platform independent manner.

Since: 1.2.0

genShortByteStringST :: Int -> ST s Word64 -> ST s ShortByteString Source #

Same as `genShortByteStringIO`, but runs in `ST`.

Since: 1.2.0

uniformByteStringM :: StatefulGen g m => Int -> g -> m ByteString Source #

Generates a pseudo-random `ByteString` of the specified size.

Since: 1.2.0

uniformDouble01M :: StatefulGen g m => g -> m Double Source #

Generates uniformly distributed `Double` in the range \([0, 1]\). Numbers are generated by generating uniform `Word64` and dividing it by \(2^{64}\). It's used to implement `UniformRange` instance for `Double`.

Since: 1.2.0

uniformDoublePositive01M :: StatefulGen g m => g -> m Double Source #

Generates uniformly distributed `Double` in the range \((0, 1]\). Number is generated as \(2^{-64}/2+\operatorname{uniformDouble01M}\). Constant is 1/2 of smallest nonzero value which could be generated by `uniformDouble01M`.

Since: 1.2.0

uniformFloat01M :: StatefulGen g m => g -> m Float Source #

Generates uniformly distributed `Float` in the range \([0, 1]\). Numbers are generated by generating uniform `Word32` and dividing it by \(2^{32}\). It's used to implement `UniformRange` instance for `Float`.

Since: 1.2.0

uniformFloatPositive01M :: StatefulGen g m => g -> m Float Source #

Generates uniformly distributed `Float` in the range \((0, 1]\). Number is generated as \(2^{-32}/2+\operatorname{uniformFloat01M}\). Constant is 1/2 of smallest nonzero value which could be generated by `uniformFloat01M`.

Since: 1.2.0

uniformEnumM :: (Enum a, Bounded a, StatefulGen g m) => g -> m a Source #

Generates uniformly distributed `Enum`. One can use it to define a `Uniform` instance:

    data Colors = Red | Green | Blue deriving (Enum, Bounded)
    instance Uniform Colors where uniformM = uniformEnumM

Since: 1.2.1

uniformEnumRM :: (Enum a, StatefulGen g m) => (a, a) -> g -> m a Source #

Generates uniformly distributed `Enum` in the given range. One can use it to define a `UniformRange` instance:

    data Colors = Red | Green | Blue deriving (Enum)
    instance UniformRange Colors where
      uniformRM = uniformEnumRM
      inInRange (lo, hi) x = isInRange (fromEnum lo, fromEnum hi) (fromEnum x)

Since: 1.2.1

# Appendix

## How to implement `StatefulGen`

Typically, a monadic pseudo-random number generator has facilities to save and restore its internal state in addition to generating pseudo-random numbers.

Here is an example instance for the monadic pseudo-random number generator from the `mwc-random` package:

    instance (s ~ PrimState m, PrimMonad m) => StatefulGen (MWC.Gen s) m where
      uniformWord8 = MWC.uniform
      uniformWord16 = MWC.uniform
      uniformWord32 = MWC.uniform
      uniformWord64 = MWC.uniform
      uniformShortByteString n g = unsafeSTToPrim (genShortByteStringST n (MWC.uniform g))

    instance PrimMonad m => FrozenGen MWC.Seed m where
      type MutableGen MWC.Seed m = MWC.Gen (PrimState m)
      thawGen = MWC.restore
      freezeGen = MWC.save

### `FrozenGen`

`FrozenGen` gives us ability to use any stateful pseudo-random number generator in its immutable form, if one exists that is. This concept is commonly known as a seed, which allows us to save and restore the actual mutable state of a pseudo-random number generator. The biggest benefit that can be drawn from a polymorphic access to a stateful pseudo-random number generator in a frozen form is the ability to serialize, deserialize and possibly even use the stateful generator in a pure setting without knowing the actual type of a generator ahead of time. For example we can write a function that accepts a frozen state of some pseudo-random number generator and produces a short list with random even integers.

    >>> import Data.Int (Int8)
    >>> :{
    myCustomRandomList :: FrozenGen f m => f -> m [Int8]
    myCustomRandomList f =
      withMutableGen_ f $ \gen -> do
        len <- uniformRM (5, 10) gen
        replicateM len $ do
          x <- uniformM gen
          pure $ if even x then x else x + 1
    :}

and later we can apply it to a frozen version of a stateful generator, such as `STGen`:

    >>> print $ runST $ myCustomRandomList (STGen (mkStdGen 217))
    [-50,-2,4,-8,-58,-40,24,-32,-110,24]

or a `Seed` from `mwc-random`:

    >>> import Data.Vector.Primitive as P
    >>> print $ runST $ myCustomRandomList (MWC.toSeed (P.fromList [1,2,3]))
    [24,40,10,40,-8,48,-78,70,-12]

Alternatively, instead of discarding the final state of the generator, as it happens above, we could have used `withMutableGen`, which together with the result would give us back its frozen form. This would allow us to store the end state of our generator somewhere for the later reuse.

## Floating point number caveats

The `UniformRange` instances for `Float` and `Double` use the following procedure to generate a random value in a range for `uniformRM (a, b) g`:

If \(a = b\), return \(a\). Otherwise:

1. Generate \(x\) uniformly such that \(0 \leq x \leq 1\).

   The method by which \(x\) is sampled does not cover all representable floating point numbers in the unit interval. The method never generates denormal floating point numbers, for example.

2. Return \(x \cdot a + (1 - x) \cdot b\).

   Due to rounding errors, floating point operations are neither associative nor distributive the way the corresponding operations on real numbers are. Additionally, floating point numbers admit special values `NaN` as well as negative and positive infinity.

For pathological values, step 2 can yield surprising results.

- The result may be greater than `max a b`.

      >>> :{
      let (a, b, x) = (-2.13238e-29, -2.1323799e-29, 0.27736077)
          result = x * a + (1 - x) * b :: Float
      in (result, result > max a b)
      :}
      (-2.1323797e-29,True)

- The result may be smaller than `min a b`.

      >>> :{
      let (a, b, x) = (-1.9087862, -1.908786, 0.4228573)
          result = x * a + (1 - x) * b :: Float
      in (result, result < min a b)
      :}
      (-1.9087863,True)

What happens when `NaN` or `Infinity` are given to `uniformRM`? We first define them as constants:

    >>> nan = read "NaN" :: Float
    >>> inf = read "Infinity" :: Float

- If at least one of \(a\) or \(b\) is `NaN`, the result is `NaN`.

      >>> let (a, b, x) = (nan, 1, 0.5) in x * a + (1 - x) * b
      NaN
      >>> let (a, b, x) = (-1, nan, 0.5) in x * a + (1 - x) * b
      NaN

- If \(a\) is `-Infinity` and \(b\) is `Infinity`, the result is `NaN`.

      >>> let (a, b, x) = (-inf, inf, 0.5) in x * a + (1 - x) * b
      NaN

- Otherwise, if \(a\) is `Infinity` or `-Infinity`, the result is \(a\).

      >>> let (a, b, x) = (inf, 1, 0.5) in x * a + (1 - x) * b
      Infinity
      >>> let (a, b, x) = (-inf, 1, 0.5) in x * a + (1 - x) * b
      -Infinity

- Otherwise, if \(b\) is `Infinity` or `-Infinity`, the result is \(b\).

      >>> let (a, b, x) = (1, inf, 0.5) in x * a + (1 - x) * b
      Infinity
      >>> let (a, b, x) = (1, -inf, 0.5) in x * a + (1 - x) * b
      -Infinity

Note that the GCC 10.1.0 C++ standard library, the Java 10 standard library and CPython 3.8 use the same procedure to generate floating point values in a range.

# References

1. Guy L. Steele, Jr., Doug Lea, and Christine H. Flood. 2014. Fast splittable pseudorandom number generators. In Proceedings of the 2014 ACM International Conference on Object Oriented Programming Systems Languages & Applications (OOPSLA '14). ACM, New York, NY, USA, 453-472. DOI: https://doi.org/10.1145/2660193.2660195