HORIZON HASKELLDocslts/ghc-10.0.x8174fa42026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8174fa4 · 2026-10-11

Modulerandom-1.3.1Haskell2010

System.Random.Internal

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

  • 4 types
  • 7 classes
  • 42 values
  • Packagerandom-1.3.1
  • Exports53
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceInternal.hs

Pure and monadic pseudo-random number generator interfaces

3 declarations
classclass RandomGen g where
#

RandomGen is an interface to pure pseudo-random number generators.

StdGen is the standard RandomGen instance provided by this library.

Methods

Instances8RandomGen, …
classclass RandomGen g => SplitGen g where
#

Pseudo-random generators that can be split into two separate and independent psuedo-random generators should provide an instance for this type class.

Historically this functionality was included in the RandomGen type class in the split function, however, few pseudo-random generators possess this property of splittability. This lead the old split function being usually implemented in terms of error.

Methods

  • splitGen :: g -> (g, g)

    Returns two distinct pseudo-random number generators.

    Implementations should take care to ensure that the resulting generators are not correlated.

Instances8SplitGen, …
newtypenewtype Seed g
#

This is a binary form of pseudo-random number generator's state. It is designed to be safe and easy to use for input/output operations like restoring from file, transmitting over the network, etc.

Constructor is not exported, becasue it is important for implementation to enforce the invariant of the underlying byte array being of the exact same length as the generator has specified in SeedSize. Use mkSeed and unSeed to get access to the raw bytes in a safe manner.

Constructors

Instances4Eq, Ord, Show, Uniform
  • Eq (Seed g)Defined in random-1.3.1 · System.Random.Internal
  • Ord (Seed g)Defined in random-1.3.1 · System.Random.Internal
  • Show (Seed g)Defined in random-1.3.1 · System.Random.Internal
  • SeedGen g => Uniform (Seed g)Defined in random-1.3.1 · System.Random.Seed · orphan

Stateful

5 declarations
classclass Monad m => StatefulGen g (m :: Type -> Type) where
#

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

Methods

Instances5StatefulGen
classclass StatefulGen (MutableGen f m) m => FrozenGen f (m :: Type -> Type) where
#

This class is designed for mutable pseudo-random number generators that have a frozen imutable counterpart that can be manipulated in pure code.

It also works great with frozen generators that are based on pure generators that have a RandomGen instance.

Here are a few laws, which are important for this type class:

  • Roundtrip and complete destruction on overwrite:

overwriteGen mg fg >> freezeGen mg = pure fg
  • Modification of a mutable generator:

overwriteGen mg fg = modifyGen mg (const ((), fg)
  • Freezing of a mutable generator:

freezeGen mg = modifyGen mg (fg -> (fg, fg))

Associated types

Methods

  • freezeGen :: MutableGen f m -> m f

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

  • modifyGen :: MutableGen f m -> (f -> (a, f)) -> m a

    Apply a pure function to the frozen pseudo-random number generator.

  • overwriteGen :: MutableGen f m -> f -> m ()

    Overwrite contents of the mutable pseudo-random number generator with the supplied frozen one

Instances5FrozenGen
classclass FrozenGen f m => ThawedGen f (m :: Type -> Type) where
#

Functionality for thawing frozen generators is not part of the FrozenGen class, becase not all mutable generators support functionality of creating new mutable generators, which is what thawing is in its essence. For this reason StateGen does not have an instance for this type class, but it has one for FrozenGen.

Here is an important law that relates this type class to FrozenGen

  • Roundtrip and independence of mutable generators:

traverse thawGen fgs >>= traverse freezeGen = pure fgs

Methods

  • thawGen :: f -> m (MutableGen f m)

    Create a new mutable pseudo-random number generator from its frozen state.

Instances4ThawedGen
valuesplitGenM :: (SplitGen f, FrozenGen f m) => MutableGen f m -> m f
#

Splits a pseudo-random number generator into two. Overwrites the mutable pseudo-random number generator with one of the immutable pseudo-random number generators produced by a split function and returns the other.

Standard pseudo-random number generator

newtypenewtype StdGen
#

The standard pseudo-random number generator.

Constructors

Instances7Eq, Show, NFData, RandomGen, SplitGen, SeedGen, …
valuemkStdGen64 :: Word64 -> StdGen
#

Constructs a StdGen deterministically from a Word64 seed.

The difference between mkStdGen is that mkStdGen64 will work the same on 64-bit and 32-bit architectures, while the former can only use 32-bit of information for initializing the psuedo-random number generator on 32-bit operating systems

Monadic adapters for pure pseudo-random number generators

0 declarations

Pure adapter

newtypenewtype StateGen g
#

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

Constructors

Instances11Eq, Ord, Show, Storable, NFData, RandomGen, …
valuerunStateGen :: RandomGen g => g -> (StateGenM g -> State g a) -> (a, g)
#

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

Examples
Example3 expressions
import System.Random.Statefullet pureGen = mkStdGen 137runStateGen pureGen randomM :: (Int, StdGen)(7879794327570578227,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
valuerunStateGen_ :: RandomGen g => g -> (StateGenM g -> State g a) -> a
#

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

Examples
Example3 expressions
import System.Random.Statefullet pureGen = mkStdGen 137runStateGen_ pureGen randomM :: Int7879794327570578227
valuerunStateGenT
  1. :: RandomGen g
  2. => g
  3. -> StateGenM g -> StateT g m a
  4. -> m (a, g)
#

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

Examples
Example3 expressions
import System.Random.Statefullet pureGen = mkStdGen 137runStateGenT pureGen randomM :: IO (Int, StdGen)(7879794327570578227,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
valuerunStateGenT_
  1. :: (RandomGen g, Functor f)
  2. => g
  3. -> StateGenM g -> StateT g f a
  4. -> f a
#

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

Examples
Example3 expressions
import System.Random.Statefullet pureGen = mkStdGen 137runStateGenT_ pureGen randomM :: IO Int7879794327570578227

Pseudo-random values of various types

15 declarations
classclass Uniform a where
#

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

Methods

  • uniformM :: StatefulGen g m => g -> m a

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

    There is a default implementation via Generic:

    Example7 expressions
    :seti -XDeriveGeneric -XDeriveAnyClassimport GHC.Generics (Generic)import System.Random.Statefuldata 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]
Instances42Uniform, …
valueuniformViaFiniteM
  1. :: (StatefulGen g m, Generic a, GFinite (Rep a))
  2. => g
  3. -> m a
#

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.

Example7 expressions
:seti -XDeriveGeneric -XDeriveAnyClassimport GHC.Generics (Generic)import System.Random.Statefuldata Triple = Triple Word8 Word8 Word8 deriving (Show, Generic, Finite)instance Uniform Triple where uniformM = uniformViaFiniteMgen <- 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]
classclass UniformRange a where
#

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

Methods

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

    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)

    The range is understood as defined by means of isInRange, so

    isInRange (a, b) <$> uniformRM (a, b) gen == pure True

    but beware of floating point number caveats.

    There is a default implementation via Generic:

    Example8 expressions
    :seti -XDeriveGeneric -XDeriveAnyClassimport GHC.Generics (Generic)import Data.Word (Word8)import Control.Monad (replicateM)import System.Random.Statefulgen <- newIOGenM (mkStdGen 42)data Tuple = Tuple Bool Word8 deriving (Show, Generic, UniformRange)replicateM 10 (uniformRM (Tuple False 100, Tuple True 150) gen)[Tuple False 102,Tuple True 118,Tuple False 115,Tuple True 113,Tuple True 126,Tuple False 127,Tuple True 130,Tuple False 113,Tuple False 150,Tuple False 125]
  • isInRange :: (a, a) -> a -> Bool

    A notion of (inclusive) ranges prescribed to a.

    Ranges are symmetric:

    isInRange (lo, hi) x == isInRange (hi, lo) x

    Ranges include their endpoints:

    isInRange (lo, hi) lo == True

    When endpoints coincide, there is nothing else:

    isInRange (x, x) y == x == y

    Endpoints are endpoints:

    isInRange (lo, hi) x ==>
    isInRange (lo, x) hi == x == hi

    Ranges are transitive relations:

    isInRange (lo, hi) lo' && isInRange (lo, hi) hi' && isInRange (lo', hi') x
    ==> isInRange (lo, hi) x

    There is a default implementation of isInRange via Generic. Other helper function that can be used for implementing this function are isInRangeOrd and isInRangeEnum.

    Note that the isRange method from Data.Ix is not a suitable default implementation of isInRange. Unlike isInRange, isRange is not required to be symmetric, and many isRange implementations are not symmetric in practice.

Instances45UniformRange, …
valueuniformEnumM :: (Enum a, Bounded a, StatefulGen g m) => g -> m a
#

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
valueuniformEnumRM :: (Enum a, StatefulGen g m) => (a, a) -> g -> m a
#

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)
valueuniformListM :: (StatefulGen g m, Uniform a) => Int -> g -> m [a]
#

Generates a list of pseudo-random values.

Examples
Example4 expressions
import System.Random.Statefullet pureGen = mkStdGen 137g <- newIOGenM pureGenuniformListM 10 g :: IO [Bool][True,True,True,True,False,True,True,False,False,False]
valueuniformListRM
  1. :: (StatefulGen g m, UniformRange a)
  2. => Int
  3. -> (a, a)
  4. -> g
  5. -> m [a]
#

Generates a list of pseudo-random values in a specified range.

Examples
Example4 expressions
import System.Random.Statefullet pureGen = mkStdGen 137g <- newIOGenM pureGenuniformListRM 10 (20, 30) g :: IO [Int][23,21,28,25,28,28,26,25,29,27]
valueisInRangeOrd :: Ord a => (a, a) -> a -> Bool
#

Utilize Ord instance to decide if a value is within the range. Designed to be used for implementing isInRange

valuescaleFloating
  1. :: (RealFloat a, Integral w, Bounded w, FiniteBits w)
  2. => a

    Low

  3. -> a

    High

  4. -> w

    Uniformly distributed unsigned integral value that will be used for converting to a floating point value and subsequent scaling to the specified range

  5. -> a
#

This is the function that is used to scale a floating point value from random word range to the custom [low, high] range.

Generators for sequences of pseudo-random bytes

7 declarations
valueuniformByteArray
  1. :: RandomGen g
  2. => Bool

    Should byte array be allocated in pinned or unpinned memory.

  3. -> Int

    Number of bytes to generate

  4. -> g

    Pure pseudo-random numer generator

  5. -> (ByteArray, g)
#

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

Helpers for dealing with MutableByteArray

valuewriteWord64LE
  1. :: MutableByteArray s
  2. -> Int

    Offset into mutable byte array in number of bytes

  3. -> Word64

    8 bytes that will be written into the supplied array

  4. -> ST s ()
#
valueindexWord8
  1. :: ByteArray
  2. -> Int

    Offset into immutable byte array in number of bytes

  3. -> Word8
#
valueindexWord64LE
  1. :: ByteArray
  2. -> Int

    Offset into immutable byte array in number of bytes

  3. -> Word64
#
valueindexByteSliceWord64LE
  1. :: ByteArray
  2. -> Int

    Starting offset in number of bytes

  3. -> Int

    Ending offset in number of bytes

  4. -> Word64
#