-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Pseudo-random number generation -- -- This package provides basic pseudo-random number generation, including -- the ability to split random number generators. -- --
-- >>> let roll = uniformR (1, 6) :: RandomGen g => g -> (Word, g) -- -- >>> let rolls = unfoldr (Just . roll) :: RandomGen g => g -> [Word] -- -- >>> let pureGen = mkStdGen 42 -- -- >>> take 10 (rolls pureGen) :: [Word] -- [1,1,3,2,4,5,3,4,6,2] ---- -- See System.Random for more details. -- --
-- >>> let rollM = uniformRM (1, 6) :: StatefulGen g m => g -> m Word -- -- >>> let pureGen = mkStdGen 42 -- -- >>> runStateGen_ pureGen (replicateM 10 . rollM) :: [Word] -- [1,1,3,2,4,5,3,4,6,2] ---- -- The monadic adapter System.Random.Stateful.runStateGen_ is used -- here to lift the pure pseudo-random number generator pureGen -- into the System.Random.Stateful.StatefulGen context. -- -- The monadic interface can also be used with existing monadic -- pseudo-random number generators. In this example, we use the one -- provided in the mwc-random package: -- --
-- >>> import System.Random.MWC as MWC -- -- >>> let rollM = uniformRM (1, 6) :: StatefulGen g m => g -> m Word -- -- >>> monadicGen <- MWC.create -- -- >>> replicateM 10 (rollM monadicGen) :: IO [Word] -- [2,3,6,6,4,4,3,1,5,4] ---- -- See System.Random.Stateful for more details. @package random @version 1.3.0 -- | This library deals with the common task of pseudo-random number -- generation. module System.Random -- | RandomGen is an interface to pure pseudo-random number -- generators. -- -- StdGen is the standard RandomGen instance provided by -- this library. class RandomGen g -- | Returns a Word8 that is uniformly distributed over the entire -- Word8 range. genWord8 :: RandomGen g => g -> (Word8, g) -- | Returns a Word16 that is uniformly distributed over the entire -- Word16 range. genWord16 :: RandomGen g => g -> (Word16, g) -- | Returns a Word32 that is uniformly distributed over the entire -- Word32 range. genWord32 :: RandomGen g => g -> (Word32, g) -- | Returns a Word64 that is uniformly distributed over the entire -- Word64 range. genWord64 :: RandomGen g => g -> (Word64, g) -- | genWord32R upperBound g returns a Word32 that is -- uniformly distributed over the range [0, upperBound]. genWord32R :: RandomGen g => Word32 -> g -> (Word32, g) -- | genWord64R upperBound g returns a Word64 that is -- uniformly distributed over the range [0, upperBound]. genWord64R :: RandomGen g => Word64 -> g -> (Word64, g) -- | Fill in the supplied MutableByteArray with uniformly generated -- random bytes. This function is unsafe because it is not required to do -- any bounds checking. For a safe variant use -- uniformFillMutableByteArrayM instead. -- -- Default type class implementation uses -- defaultUnsafeUniformFillMutableByteArray. unsafeUniformFillMutableByteArray :: RandomGen g => MutableByteArray s -> Int -> Int -> g -> ST s g -- | Returns two distinct pseudo-random number generators. -- -- Implementations should take care to ensure that the resulting -- generators are not correlated. Some pseudo-random number generators -- are not splittable. In that case, the split implementation -- should fail with a descriptive error message. -- | Deprecated: In favor of splitGen split :: RandomGen g => g -> (g, g) -- | Returns two distinct pseudo-random number generators. -- -- Implementations should take care to ensure that the resulting -- generators are not correlated. Some pseudo-random number generators -- are not splittable. In that case, the split implementation -- should fail with a descriptive error message. -- | Deprecated: In favor of splitGen split :: (RandomGen g, SplitGen g) => g -> (g, g) -- | 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. class RandomGen g => SplitGen g -- | Returns two distinct pseudo-random number generators. -- -- Implementations should take care to ensure that the resulting -- generators are not correlated. splitGen :: SplitGen g => g -> (g, g) -- | Generates a value uniformly distributed over all possible values of -- that type. -- -- This is a pure version of uniformM. -- --
-- >>> import System.Random
--
-- >>> let pureGen = mkStdGen 137
--
-- >>> uniform pureGen :: (Bool, StdGen)
-- (True,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
--
-- You can use type applications to disambiguate the type of the
-- generated numbers:
--
--
-- >>> :seti -XTypeApplications
--
-- >>> uniform @Bool pureGen
-- (True,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
uniform :: (Uniform a, RandomGen g) => g -> (a, g)
-- | Generates a value uniformly distributed over the provided range, which
-- is interpreted as inclusive in the lower and upper bound.
--
-- -- uniformR (a, b) = uniformR (b, a) ---- -- This is a pure version of uniformRM. -- --
-- >>> import System.Random
--
-- >>> let pureGen = mkStdGen 137
--
-- >>> uniformR (1 :: Int, 4 :: Int) pureGen
-- (4,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
--
-- You can use type applications to disambiguate the type of the
-- generated numbers:
--
--
-- >>> :seti -XTypeApplications
--
-- >>> uniformR @Int (1, 4) pureGen
-- (4,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
uniformR :: (UniformRange a, RandomGen g) => (a, a) -> g -> (a, g)
-- | The class of types for which random values can be generated. Most
-- instances of Random will produce values that are uniformly
-- distributed on the full range, but for those types without a
-- well-defined "full range" some sensible default subrange will be
-- selected.
--
-- Random exists primarily for backwards compatibility with
-- version 1.1 of this library. In new code, use the better specified
-- Uniform and UniformRange instead.
class Random a
-- | Takes a range (lo,hi) and a pseudo-random number generator
-- g, and returns a pseudo-random value uniformly distributed over
-- the closed interval [lo,hi], together with a new generator. It
-- is unspecified what happens if lo>hi, but usually the values
-- will simply get swapped.
--
--
-- >>> let gen = mkStdGen 26
--
-- >>> fst $ randomR ('a', 'z') gen
-- 'z'
--
-- >>> fst $ randomR ('a', 'z') gen
-- 'z'
--
--
-- For continuous types there is no requirement that the values lo
-- and hi are ever produced, but they may be, depending on the
-- implementation and the interval.
--
-- There is no requirement to follow the Ord instance and the
-- concept of range can be defined on per type basis. For example product
-- types will treat their values independently:
--
--
-- >>> fst $ randomR (('a', 5.0), ('z', 10.0)) $ mkStdGen 26
-- ('z',5.22694980853051)
--
--
-- In case when a lawful range is desired uniformR should be used
-- instead.
randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g)
-- | Takes a range (lo,hi) and a pseudo-random number generator
-- g, and returns a pseudo-random value uniformly distributed over
-- the closed interval [lo,hi], together with a new generator. It
-- is unspecified what happens if lo>hi, but usually the values
-- will simply get swapped.
--
--
-- >>> let gen = mkStdGen 26
--
-- >>> fst $ randomR ('a', 'z') gen
-- 'z'
--
-- >>> fst $ randomR ('a', 'z') gen
-- 'z'
--
--
-- For continuous types there is no requirement that the values lo
-- and hi are ever produced, but they may be, depending on the
-- implementation and the interval.
--
-- There is no requirement to follow the Ord instance and the
-- concept of range can be defined on per type basis. For example product
-- types will treat their values independently:
--
--
-- >>> fst $ randomR (('a', 5.0), ('z', 10.0)) $ mkStdGen 26
-- ('z',5.22694980853051)
--
--
-- In case when a lawful range is desired uniformR should be used
-- instead.
randomR :: (Random a, RandomGen g, UniformRange a) => (a, a) -> g -> (a, g)
-- | The same as randomR, but using a default range determined by
-- the type:
--
-- -- >>> :seti -XDeriveGeneric -XDeriveAnyClass -- -- >>> import GHC.Generics (Generic) -- -- >>> data MyBool = MyTrue | MyFalse deriving (Generic, Finite) -- -- >>> data Action = Code MyBool | Eat (Maybe Bool) | Sleep deriving (Generic, Finite) --class Finite a -- | Interface for converting a pure pseudo-random number generator to and -- from non-empty sequence of bytes. Seeds are stored in Little-Endian -- order regardless of the platform it is being used on, which provides -- cross-platform compatibility, while providing optimal performance for -- the most common platform type. -- -- Conversion to and from a Seed serves as a building block for -- implementing serialization for any pure or frozen pseudo-random number -- generator. -- -- It is not trivial to implement platform independence. For this reason -- this type class has two alternative ways of creating an instance for -- this class. The easiest way for constructing a platform indepent seed -- is by converting the inner state of a generator to and from a list of -- 64 bit words using toSeed64 and fromSeed64 respectively. -- In that case cross-platform support will be handled automaticaly. -- --
-- >>> :set -XDataKinds -XTypeFamilies
--
-- >>> import Data.Word (Word8, Word32)
--
-- >>> import Data.Bits ((.|.), shiftR, shiftL)
--
-- >>> import Data.List.NonEmpty (NonEmpty ((:|)))
--
-- >>> data FiveByteGen = FiveByteGen Word8 Word32 deriving Show
--
-- >>> :{
-- instance SeedGen FiveByteGen where
-- type SeedSize FiveByteGen = 5
-- fromSeed64 (w64 :| _) =
-- FiveByteGen (fromIntegral (w64 `shiftR` 32)) (fromIntegral w64)
-- toSeed64 (FiveByteGen x1 x4) =
-- let w64 = (fromIntegral x1 `shiftL` 32) .|. fromIntegral x4
-- in (w64 :| [])
-- :}
--
--
-- -- >>> FiveByteGen 0x80 0x01020304 -- FiveByteGen 128 16909060 -- -- >>> fromSeed (toSeed (FiveByteGen 0x80 0x01020304)) -- FiveByteGen 128 16909060 -- -- >>> toSeed (FiveByteGen 0x80 0x01020304) -- Seed [0x04, 0x03, 0x02, 0x01, 0x80] -- -- >>> toSeed64 (FiveByteGen 0x80 0x01020304) -- 549772722948 :| [] ---- -- However, when performance is of utmost importance or default handling -- of cross platform independence is not sufficient, then an adventurous -- developer can try implementing conversion into bytes directly with -- toSeed and fromSeed. -- -- Properties that must hold: -- --
-- > fromSeed (toSeed gen) == gen ---- --
-- > fromSeed64 (toSeed64 gen) == gen ---- -- Note, that there is no requirement for every Seed to roundtrip, -- eg. this proprty does not even hold for StdGen: -- --
-- >>> let seed = nonEmptyToSeed (0xab :| [0xff00]) :: Seed StdGen -- -- >>> seed == toSeed (fromSeed seed) -- False --class (KnownNat (SeedSize g), 1 <= SeedSize g, Typeable g) => SeedGen g where { -- | Number of bytes that is required for storing the full state of a -- pseudo-random number generator. It should be big enough to satisfy the -- roundtrip property: -- --
-- > fromSeed (toSeed gen) == gen
--
type SeedSize g :: Nat;
}
-- | Convert from a binary representation to a pseudo-random number
-- generator
fromSeed :: SeedGen g => Seed g -> g
-- | Convert to a binary representation of a pseudo-random number generator
toSeed :: SeedGen g => g -> Seed g
-- | Construct pseudo-random number generator from a list of words.
-- Whenever list does not have enough bytes to satisfy the
-- SeedSize requirement, it will be padded with zeros. On the
-- other hand when it has more than necessary, extra bytes will be
-- dropped.
--
-- For example if SeedSize is set to 2, then only the lower 16
-- bits of the first element in the list will be used.
fromSeed64 :: SeedGen g => NonEmpty Word64 -> g
-- | Convert pseudo-random number generator to a list of words
--
-- In case when SeedSize is not a multiple of 8, then the upper
-- bits of the last word in the list will be set to zero.
toSeed64 :: SeedGen g => g -> NonEmpty Word64
-- | 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 mkSize and unSize to get access to
-- the raw bytes in a safe manner.
data Seed g
-- | Get the expected size of the Seed in number bytes
seedSize :: forall g. SeedGen g => Int
-- | Just like seedSize, except it accepts a proxy as an argument.
seedSizeProxy :: forall proxy g. SeedGen g => proxy g -> Int
-- | Construct a Seed from a ByteArray of expected length.
-- Whenever ByteArray does not match the SeedSize specified
-- by the pseudo-random generator, this function will fail.
mkSeed :: forall g m. (SeedGen g, MonadFail m) => ByteArray -> m (Seed g)
-- | Unwrap the Seed and get the underlying ByteArray
unSeed :: Seed g -> ByteArray
-- | Just like mkSeed, but uses ByteString as argument.
-- Results in a memcopy of the seed.
mkSeedFromByteString :: (SeedGen g, MonadFail m) => ByteString -> m (Seed g)
-- | Just like unSeed, but produced a ByteString. Results
-- in a memcopy of the seed.
unSeedToByteString :: Seed g -> ByteString
-- | Helper function that allows for operating directly on the Seed,
-- while supplying a function that uses the pseudo-random number
-- generator that is constructed from that Seed.
--
-- -- >>> :set -XTypeApplications -- -- >>> import System.Random -- -- >>> withSeed (nonEmptyToSeed (pure 2024) :: Seed StdGen) (uniform @Int) -- (1039666877624726199,Seed [0xe9, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) --withSeed :: SeedGen g => Seed g -> (g -> (a, g)) -> (a, Seed g) -- | Same as withSeed, except it is useful with monadic computation -- and frozen generators. -- -- See withSeedMutableGen for a helper that also handles seeds for -- mutable pseduo-random number generators. withSeedM :: (SeedGen g, Functor f) => Seed g -> (g -> f (a, g)) -> f (a, Seed g) -- | Read the seed from a file and use it for constructing a pseudo-random -- number generator. After supplied action has been applied to the -- constructed generator, the resulting generator will be converted back -- to a seed and written to the same file. withSeedFile :: (SeedGen g, MonadIO m) => FilePath -> (Seed g -> m (a, Seed g)) -> m a -- | This is a function that shows the name of the generator type, which is -- useful for error reporting. seedGenTypeName :: forall g. SeedGen g => String -- | Construct a seed from a list of 64-bit words. At most SeedSize -- many bytes will be used. nonEmptyToSeed :: forall g. SeedGen g => NonEmpty Word64 -> Seed g -- | Convert a Seed to a list of 64bit words. nonEmptyFromSeed :: forall g. SeedGen g => Seed g -> NonEmpty Word64 -- | Produce an infinite list of pseudo-random values. Integrates nicely -- with list fusion. Naturally, there is no way to recover the final -- generator, therefore either use split before calling -- uniforms or use uniformList instead. -- -- Similar to randoms, except it relies on Uniform type -- class instead of Random -- --
-- >>> let gen = mkStdGen 2023 -- -- >>> import Data.Word (Word16) -- -- >>> take 5 $ uniforms gen :: [Word16] -- [56342,15850,25292,14347,13919] --uniforms :: (Uniform a, RandomGen g) => g -> [a] -- | Produce an infinite list of pseudo-random values in a specified range. -- Same as uniforms, integrates nicely with list fusion. There is -- no way to recover the final generator, therefore either use -- split before calling uniformRs or use -- uniformListR instead. -- -- Similar to randomRs, except it relies on UniformRange -- type class instead of Random. -- --
-- >>> let gen = mkStdGen 2023 -- -- >>> take 5 $ uniformRs (10, 100) gen :: [Int] -- [32,86,21,57,39] --uniformRs :: (UniformRange a, RandomGen g) => (a, a) -> g -> [a] -- | Produce a list of the supplied length with elements generated -- uniformly. -- -- See uniformListM for a stateful counterpart. -- --
-- >>> let gen = mkStdGen 2023
--
-- >>> import Data.Word (Word16)
--
-- >>> uniformList 5 gen :: ([Word16], StdGen)
-- ([56342,15850,25292,14347,13919],StdGen {unStdGen = SMGen 6446154349414395371 1920468677557965761})
--
uniformList :: (Uniform a, RandomGen g) => Int -> g -> ([a], g)
-- | Produce a list of the supplied length with elements generated
-- uniformly.
--
-- See uniformListM for a stateful counterpart.
--
--
-- >>> let gen = mkStdGen 2023
--
-- >>> uniformListR 10 (20, 30) gen :: ([Int], StdGen)
-- ([26,30,27,24,30,25,27,21,27,27],StdGen {unStdGen = SMGen 12965503083958398648 1920468677557965761})
--
uniformListR :: (UniformRange a, RandomGen g) => Int -> (a, a) -> g -> ([a], g)
-- | Shuffle elements of a list in a uniformly random order.
--
--
-- >>> uniformShuffleList "ELVIS" $ mkStdGen 252
-- ("LIVES",StdGen {unStdGen = SMGen 17676540583805057877 5302934877338729551})
--
uniformShuffleList :: RandomGen g => [a] -> g -> ([a], g)
-- | Efficiently generates a sequence of pseudo-random bytes in a platform
-- independent manner.
uniformByteArray :: RandomGen g => Bool -> Int -> g -> (ByteArray, g)
-- | Generates a ByteString of the specified size using a pure
-- pseudo-random number generator. See uniformByteStringM for
-- the monadic version.
--
-- -- >>> import System.Random -- -- >>> import Data.ByteString (unpack) -- -- >>> let pureGen = mkStdGen 137 -- -- >>> unpack . fst $ uniformByteString 10 pureGen -- [51,123,251,37,49,167,90,109,1,4] --uniformByteString :: RandomGen g => Int -> g -> (ByteString, g) -- | Same as uniformByteArray False, but for -- ShortByteString. -- -- Returns a ShortByteString of length n filled with -- pseudo-random bytes. -- --
-- >>> import System.Random -- -- >>> import Data.ByteString.Short (unpack) -- -- >>> let pureGen = mkStdGen 137 -- -- >>> unpack . fst $ uniformShortByteString 10 pureGen -- [51,123,251,37,49,167,90,109,1,4] --uniformShortByteString :: RandomGen g => Int -> g -> (ShortByteString, g) -- | Fill in a slice of a mutable byte array with randomly generated bytes. -- This function does not fail, instead it clamps the offset and number -- of bytes to generate into a valid range. uniformFillMutableByteArray :: RandomGen g => MutableByteArray s -> Int -> Int -> g -> ST s g -- | Generates a ByteString of the specified size using a pure -- pseudo-random number generator. See uniformByteStringM for -- the monadic version. -- --
-- >>> import System.Random -- -- >>> import Data.ByteString -- -- >>> let pureGen = mkStdGen 137 -- -- >>> :seti -Wno-deprecations -- -- >>> unpack . fst . genByteString 10 $ pureGen -- [51,123,251,37,49,167,90,109,1,4] ---- | Deprecated: In favor of uniformByteString genByteString :: RandomGen g => Int -> g -> (ByteString, g) -- | Same as uniformByteArray False, but for -- ShortByteString. -- -- genShortByteString n g returns a ShortByteString of -- length n filled with pseudo-random bytes. -- -- Note - This function will be removed from the type class in the -- next major release as it is no longer needed because of -- unsafeUniformFillMutableByteArray. -- | Deprecated: In favor of uniformShortByteString genShortByteString :: RandomGen g => Int -> g -> (ShortByteString, g) -- | The standard pseudo-random number generator. data StdGen -- | Constructs a StdGen deterministically from an Int seed. -- See mkStdGen64 for a Word64 variant that is architecture -- agnostic. mkStdGen :: Int -> 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 mkStdGen64 :: Word64 -> StdGen -- | Initialize StdGen using system entropy (i.e. -- /dev/urandom) when it is available, while falling back on -- using system time as the seed. initStdGen :: MonadIO m => m StdGen -- | Uses the supplied function to get a value from the current global -- random generator, and updates the global generator with the new -- generator returned by the function. For example, rollDice -- produces a pseudo-random integer between 1 and 6: -- --
-- >>> rollDice = getStdRandom (randomR (1, 6)) -- -- >>> replicateM 10 (rollDice :: IO Int) -- [1,1,1,4,5,6,1,2,2,5] ---- -- This is an outdated function and it is recommended to switch to its -- equivalent applyAtomicGen instead, possibly with the -- globalStdGen if relying on the global state is acceptable. -- --
-- >>> import System.Random.Stateful -- -- >>> rollDice = applyAtomicGen (uniformR (1, 6)) globalStdGen -- -- >>> replicateM 10 (rollDice :: IO Int) -- [2,1,1,5,4,3,6,6,3,2] --getStdRandom :: MonadIO m => (StdGen -> (a, StdGen)) -> m a -- | Gets the global pseudo-random number generator. Extracts the contents -- of globalStdGen getStdGen :: MonadIO m => m StdGen -- | Sets the global pseudo-random number generator. Overwrites the -- contents of globalStdGen setStdGen :: MonadIO m => StdGen -> m () -- | Applies split to the current global pseudo-random generator -- globalStdGen, updates it with one of the results, and returns -- the other. newStdGen :: MonadIO m => m StdGen -- | A variant of randomM that uses the global pseudo-random number -- generator globalStdGen. -- --
-- >>> import Data.Int -- -- >>> randomIO :: IO Int32 -- 114794456 ---- -- This function is equivalent to getStdRandom -- random and is included in this interface for historical -- reasons and backwards compatibility. It is recommended to use -- uniformM instead, possibly with the globalStdGen if -- relying on the global state is acceptable. -- --
-- >>> import System.Random.Stateful -- -- >>> uniformM globalStdGen :: IO Int32 -- -1768545016 --randomIO :: (Random a, MonadIO m) => m a -- | A variant of randomRM that uses the global pseudo-random number -- generator globalStdGen -- --
-- >>> randomRIO (2020, 2100) :: IO Int -- 2028 ---- -- Similar to randomIO, this function is equivalent to -- getStdRandom randomR and is included in this -- interface for historical reasons and backwards compatibility. It is -- recommended to use uniformRM instead, possibly with the -- globalStdGen if relying on the global state is acceptable. -- --
-- >>> import System.Random.Stateful -- -- >>> uniformRM (2020, 2100) globalStdGen :: IO Int -- 2044 --randomRIO :: (Random a, MonadIO m) => (a, a) -> m a -- | Yields the range of values returned by next. -- -- It is required that: -- --
-- >>> let gen = mkStdGen 26
--
-- >>> fst $ randomR ('a', 'z') gen
-- 'z'
--
-- >>> fst $ randomR ('a', 'z') gen
-- 'z'
--
--
-- For continuous types there is no requirement that the values lo
-- and hi are ever produced, but they may be, depending on the
-- implementation and the interval.
--
-- There is no requirement to follow the Ord instance and the
-- concept of range can be defined on per type basis. For example product
-- types will treat their values independently:
--
--
-- >>> fst $ randomR (('a', 5.0), ('z', 10.0)) $ mkStdGen 26
-- ('z',5.22694980853051)
--
--
-- In case when a lawful range is desired uniformR should be used
-- instead.
randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g)
-- | Takes a range (lo,hi) and a pseudo-random number generator
-- g, and returns a pseudo-random value uniformly distributed over
-- the closed interval [lo,hi], together with a new generator. It
-- is unspecified what happens if lo>hi, but usually the values
-- will simply get swapped.
--
--
-- >>> let gen = mkStdGen 26
--
-- >>> fst $ randomR ('a', 'z') gen
-- 'z'
--
-- >>> fst $ randomR ('a', 'z') gen
-- 'z'
--
--
-- For continuous types there is no requirement that the values lo
-- and hi are ever produced, but they may be, depending on the
-- implementation and the interval.
--
-- There is no requirement to follow the Ord instance and the
-- concept of range can be defined on per type basis. For example product
-- types will treat their values independently:
--
--
-- >>> fst $ randomR (('a', 5.0), ('z', 10.0)) $ mkStdGen 26
-- ('z',5.22694980853051)
--
--
-- In case when a lawful range is desired uniformR should be used
-- instead.
randomR :: (Random a, RandomGen g, UniformRange a) => (a, a) -> g -> (a, g)
-- | The same as randomR, but using a default range determined by
-- the type:
--
-- -- >>> :seti -XDeriveGeneric -XDeriveAnyClass -- -- >>> import GHC.Generics (Generic) -- -- >>> data MyBool = MyTrue | MyFalse deriving (Generic, Finite) -- -- >>> data Action = Code MyBool | Eat (Maybe Bool) | Sleep deriving (Generic, Finite) --class Finite a -- | 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 mkSize and unSize to get access to -- the raw bytes in a safe manner. data Seed g -- | The standard pseudo-random number generator. data StdGen -- | Interface for converting a pure pseudo-random number generator to and -- from non-empty sequence of bytes. Seeds are stored in Little-Endian -- order regardless of the platform it is being used on, which provides -- cross-platform compatibility, while providing optimal performance for -- the most common platform type. -- -- Conversion to and from a Seed serves as a building block for -- implementing serialization for any pure or frozen pseudo-random number -- generator. -- -- It is not trivial to implement platform independence. For this reason -- this type class has two alternative ways of creating an instance for -- this class. The easiest way for constructing a platform indepent seed -- is by converting the inner state of a generator to and from a list of -- 64 bit words using toSeed64 and fromSeed64 respectively. -- In that case cross-platform support will be handled automaticaly. -- --
-- >>> :set -XDataKinds -XTypeFamilies
--
-- >>> import Data.Word (Word8, Word32)
--
-- >>> import Data.Bits ((.|.), shiftR, shiftL)
--
-- >>> import Data.List.NonEmpty (NonEmpty ((:|)))
--
-- >>> data FiveByteGen = FiveByteGen Word8 Word32 deriving Show
--
-- >>> :{
-- instance SeedGen FiveByteGen where
-- type SeedSize FiveByteGen = 5
-- fromSeed64 (w64 :| _) =
-- FiveByteGen (fromIntegral (w64 `shiftR` 32)) (fromIntegral w64)
-- toSeed64 (FiveByteGen x1 x4) =
-- let w64 = (fromIntegral x1 `shiftL` 32) .|. fromIntegral x4
-- in (w64 :| [])
-- :}
--
--
-- -- >>> FiveByteGen 0x80 0x01020304 -- FiveByteGen 128 16909060 -- -- >>> fromSeed (toSeed (FiveByteGen 0x80 0x01020304)) -- FiveByteGen 128 16909060 -- -- >>> toSeed (FiveByteGen 0x80 0x01020304) -- Seed [0x04, 0x03, 0x02, 0x01, 0x80] -- -- >>> toSeed64 (FiveByteGen 0x80 0x01020304) -- 549772722948 :| [] ---- -- However, when performance is of utmost importance or default handling -- of cross platform independence is not sufficient, then an adventurous -- developer can try implementing conversion into bytes directly with -- toSeed and fromSeed. -- -- Properties that must hold: -- --
-- > fromSeed (toSeed gen) == gen ---- --
-- > fromSeed64 (toSeed64 gen) == gen ---- -- Note, that there is no requirement for every Seed to roundtrip, -- eg. this proprty does not even hold for StdGen: -- --
-- >>> let seed = nonEmptyToSeed (0xab :| [0xff00]) :: Seed StdGen -- -- >>> seed == toSeed (fromSeed seed) -- False --class (KnownNat (SeedSize g), 1 <= SeedSize g, Typeable g) => SeedGen g where { -- | Number of bytes that is required for storing the full state of a -- pseudo-random number generator. It should be big enough to satisfy the -- roundtrip property: -- --
-- > fromSeed (toSeed gen) == gen
--
type SeedSize g :: Nat;
}
-- | Convert from a binary representation to a pseudo-random number
-- generator
fromSeed :: SeedGen g => Seed g -> g
-- | Convert to a binary representation of a pseudo-random number generator
toSeed :: SeedGen g => g -> Seed g
-- | Construct pseudo-random number generator from a list of words.
-- Whenever list does not have enough bytes to satisfy the
-- SeedSize requirement, it will be padded with zeros. On the
-- other hand when it has more than necessary, extra bytes will be
-- dropped.
--
-- For example if SeedSize is set to 2, then only the lower 16
-- bits of the first element in the list will be used.
fromSeed64 :: SeedGen g => NonEmpty Word64 -> g
-- | Convert pseudo-random number generator to a list of words
--
-- In case when SeedSize is not a multiple of 8, then the upper
-- bits of the last word in the list will be set to zero.
toSeed64 :: SeedGen g => g -> NonEmpty Word64
-- | Generates a value uniformly distributed over all possible values of
-- that type.
--
-- This is a pure version of uniformM.
--
--
-- >>> import System.Random
--
-- >>> let pureGen = mkStdGen 137
--
-- >>> uniform pureGen :: (Bool, StdGen)
-- (True,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
--
-- You can use type applications to disambiguate the type of the
-- generated numbers:
--
--
-- >>> :seti -XTypeApplications
--
-- >>> uniform @Bool pureGen
-- (True,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
uniform :: (Uniform a, RandomGen g) => g -> (a, g)
-- | Generates a value uniformly distributed over the provided range, which
-- is interpreted as inclusive in the lower and upper bound.
--
-- -- uniformR (a, b) = uniformR (b, a) ---- -- This is a pure version of uniformRM. -- --
-- >>> import System.Random
--
-- >>> let pureGen = mkStdGen 137
--
-- >>> uniformR (1 :: Int, 4 :: Int) pureGen
-- (4,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
--
-- You can use type applications to disambiguate the type of the
-- generated numbers:
--
--
-- >>> :seti -XTypeApplications
--
-- >>> uniformR @Int (1, 4) pureGen
-- (4,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
uniformR :: (UniformRange a, RandomGen g) => (a, a) -> g -> (a, g)
-- | Produce an infinite list of pseudo-random values. Integrates nicely
-- with list fusion. Naturally, there is no way to recover the final
-- generator, therefore either use split before calling
-- uniforms or use uniformList instead.
--
-- Similar to randoms, except it relies on Uniform type
-- class instead of Random
--
-- -- >>> let gen = mkStdGen 2023 -- -- >>> import Data.Word (Word16) -- -- >>> take 5 $ uniforms gen :: [Word16] -- [56342,15850,25292,14347,13919] --uniforms :: (Uniform a, RandomGen g) => g -> [a] -- | Produce an infinite list of pseudo-random values in a specified range. -- Same as uniforms, integrates nicely with list fusion. There is -- no way to recover the final generator, therefore either use -- split before calling uniformRs or use -- uniformListR instead. -- -- Similar to randomRs, except it relies on UniformRange -- type class instead of Random. -- --
-- >>> let gen = mkStdGen 2023 -- -- >>> take 5 $ uniformRs (10, 100) gen :: [Int] -- [32,86,21,57,39] --uniformRs :: (UniformRange a, RandomGen g) => (a, a) -> g -> [a] -- | Produce a list of the supplied length with elements generated -- uniformly. -- -- See uniformListM for a stateful counterpart. -- --
-- >>> let gen = mkStdGen 2023
--
-- >>> import Data.Word (Word16)
--
-- >>> uniformList 5 gen :: ([Word16], StdGen)
-- ([56342,15850,25292,14347,13919],StdGen {unStdGen = SMGen 6446154349414395371 1920468677557965761})
--
uniformList :: (Uniform a, RandomGen g) => Int -> g -> ([a], g)
-- | Produce a list of the supplied length with elements generated
-- uniformly.
--
-- See uniformListM for a stateful counterpart.
--
--
-- >>> let gen = mkStdGen 2023
--
-- >>> uniformListR 10 (20, 30) gen :: ([Int], StdGen)
-- ([26,30,27,24,30,25,27,21,27,27],StdGen {unStdGen = SMGen 12965503083958398648 1920468677557965761})
--
uniformListR :: (UniformRange a, RandomGen g) => Int -> (a, a) -> g -> ([a], g)
-- | Shuffle elements of a list in a uniformly random order.
--
--
-- >>> uniformShuffleList "ELVIS" $ mkStdGen 252
-- ("LIVES",StdGen {unStdGen = SMGen 17676540583805057877 5302934877338729551})
--
uniformShuffleList :: RandomGen g => [a] -> g -> ([a], g)
-- | Efficiently generates a sequence of pseudo-random bytes in a platform
-- independent manner.
uniformByteArray :: RandomGen g => Bool -> Int -> g -> (ByteArray, g)
-- | Generates a ByteString of the specified size using a pure
-- pseudo-random number generator. See uniformByteStringM for
-- the monadic version.
--
-- -- >>> import System.Random -- -- >>> import Data.ByteString (unpack) -- -- >>> let pureGen = mkStdGen 137 -- -- >>> unpack . fst $ uniformByteString 10 pureGen -- [51,123,251,37,49,167,90,109,1,4] --uniformByteString :: RandomGen g => Int -> g -> (ByteString, g) -- | Fill in a slice of a mutable byte array with randomly generated bytes. -- This function does not fail, instead it clamps the offset and number -- of bytes to generate into a valid range. uniformFillMutableByteArray :: RandomGen g => MutableByteArray s -> Int -> Int -> g -> ST s g -- | Generates a ByteString of the specified size using a pure -- pseudo-random number generator. See uniformByteStringM for -- the monadic version. -- --
-- >>> import System.Random -- -- >>> import Data.ByteString -- -- >>> let pureGen = mkStdGen 137 -- -- >>> :seti -Wno-deprecations -- -- >>> unpack . fst . genByteString 10 $ pureGen -- [51,123,251,37,49,167,90,109,1,4] ---- | Deprecated: In favor of uniformByteString genByteString :: RandomGen g => Int -> g -> (ByteString, g) -- | Constructs a StdGen deterministically from an Int seed. -- See mkStdGen64 for a Word64 variant that is architecture -- agnostic. mkStdGen :: Int -> 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 mkStdGen64 :: Word64 -> StdGen -- | Initialize StdGen using system entropy (i.e. -- /dev/urandom) when it is available, while falling back on -- using system time as the seed. initStdGen :: MonadIO m => m StdGen -- | Uses the supplied function to get a value from the current global -- random generator, and updates the global generator with the new -- generator returned by the function. For example, rollDice -- produces a pseudo-random integer between 1 and 6: -- --
-- >>> rollDice = getStdRandom (randomR (1, 6)) -- -- >>> replicateM 10 (rollDice :: IO Int) -- [1,1,1,4,5,6,1,2,2,5] ---- -- This is an outdated function and it is recommended to switch to its -- equivalent applyAtomicGen instead, possibly with the -- globalStdGen if relying on the global state is acceptable. -- --
-- >>> import System.Random.Stateful -- -- >>> rollDice = applyAtomicGen (uniformR (1, 6)) globalStdGen -- -- >>> replicateM 10 (rollDice :: IO Int) -- [2,1,1,5,4,3,6,6,3,2] --getStdRandom :: MonadIO m => (StdGen -> (a, StdGen)) -> m a -- | Gets the global pseudo-random number generator. Extracts the contents -- of globalStdGen getStdGen :: MonadIO m => m StdGen -- | Sets the global pseudo-random number generator. Overwrites the -- contents of globalStdGen setStdGen :: MonadIO m => StdGen -> m () -- | Applies split to the current global pseudo-random generator -- globalStdGen, updates it with one of the results, and returns -- the other. newStdGen :: MonadIO m => m StdGen -- | A variant of randomM that uses the global pseudo-random number -- generator globalStdGen. -- --
-- >>> import Data.Int -- -- >>> randomIO :: IO Int32 -- 114794456 ---- -- This function is equivalent to getStdRandom -- random and is included in this interface for historical -- reasons and backwards compatibility. It is recommended to use -- uniformM instead, possibly with the globalStdGen if -- relying on the global state is acceptable. -- --
-- >>> import System.Random.Stateful -- -- >>> uniformM globalStdGen :: IO Int32 -- -1768545016 --randomIO :: (Random a, MonadIO m) => m a -- | A variant of randomRM that uses the global pseudo-random number -- generator globalStdGen -- --
-- >>> randomRIO (2020, 2100) :: IO Int -- 2028 ---- -- Similar to randomIO, this function is equivalent to -- getStdRandom randomR and is included in this -- interface for historical reasons and backwards compatibility. It is -- recommended to use uniformRM instead, possibly with the -- globalStdGen if relying on the global state is acceptable. -- --
-- >>> import System.Random.Stateful -- -- >>> uniformRM (2020, 2100) globalStdGen :: IO Int -- 2044 --randomRIO :: (Random a, MonadIO m) => (a, a) -> m a -- | Get the expected size of the Seed in number bytes seedSize :: forall g. SeedGen g => Int -- | Just like seedSize, except it accepts a proxy as an argument. seedSizeProxy :: forall proxy g. SeedGen g => proxy g -> Int -- | Construct a Seed from a ByteArray of expected length. -- Whenever ByteArray does not match the SeedSize specified -- by the pseudo-random generator, this function will fail. mkSeed :: forall g m. (SeedGen g, MonadFail m) => ByteArray -> m (Seed g) -- | Unwrap the Seed and get the underlying ByteArray unSeed :: Seed g -> ByteArray -- | Just like mkSeed, but uses ByteString as argument. -- Results in a memcopy of the seed. mkSeedFromByteString :: (SeedGen g, MonadFail m) => ByteString -> m (Seed g) -- | Just like unSeed, but produced a ByteString. Results -- in a memcopy of the seed. unSeedToByteString :: Seed g -> ByteString -- | Helper function that allows for operating directly on the Seed, -- while supplying a function that uses the pseudo-random number -- generator that is constructed from that Seed. -- --
-- >>> :set -XTypeApplications -- -- >>> import System.Random -- -- >>> withSeed (nonEmptyToSeed (pure 2024) :: Seed StdGen) (uniform @Int) -- (1039666877624726199,Seed [0xe9, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) --withSeed :: SeedGen g => Seed g -> (g -> (a, g)) -> (a, Seed g) -- | Same as withSeed, except it is useful with monadic computation -- and frozen generators. -- -- See withSeedMutableGen for a helper that also handles seeds for -- mutable pseduo-random number generators. withSeedM :: (SeedGen g, Functor f) => Seed g -> (g -> f (a, g)) -> f (a, Seed g) -- | Read the seed from a file and use it for constructing a pseudo-random -- number generator. After supplied action has been applied to the -- constructed generator, the resulting generator will be converted back -- to a seed and written to the same file. withSeedFile :: (SeedGen g, MonadIO m) => FilePath -> (Seed g -> m (a, Seed g)) -> m a -- | This is a function that shows the name of the generator type, which is -- useful for error reporting. seedGenTypeName :: forall g. SeedGen g => String -- | Construct a seed from a list of 64-bit words. At most SeedSize -- many bytes will be used. nonEmptyToSeed :: forall g. SeedGen g => NonEmpty Word64 -> Seed g -- | Convert a Seed to a list of 64bit words. nonEmptyFromSeed :: forall g. SeedGen g => Seed g -> NonEmpty Word64 -- | StatefulGen is an interface to monadic pseudo-random number -- generators. class Monad m => StatefulGen g m -- | uniformWord32R upperBound g generates a Word32 that is -- uniformly distributed over the range [0, upperBound]. uniformWord32R :: StatefulGen g m => Word32 -> g -> m Word32 -- | uniformWord64R upperBound g generates a Word64 that is -- uniformly distributed over the range [0, upperBound]. uniformWord64R :: StatefulGen g m => Word64 -> g -> m Word64 -- | Generates a Word8 that is uniformly distributed over the entire -- Word8 range. -- -- The default implementation extracts a Word8 from -- uniformWord32. uniformWord8 :: StatefulGen g m => g -> m Word8 -- | Generates a Word16 that is uniformly distributed over the -- entire Word16 range. -- -- The default implementation extracts a Word16 from -- uniformWord32. uniformWord16 :: StatefulGen g m => g -> m Word16 -- | Generates a Word32 that is uniformly distributed over the -- entire Word32 range. -- -- The default implementation extracts a Word32 from -- uniformWord64. uniformWord32 :: StatefulGen g m => g -> m Word32 -- | Generates a Word64 that is uniformly distributed over the -- entire Word64 range. -- -- The default implementation combines two Word32 from -- uniformWord32 into one Word64. uniformWord64 :: StatefulGen g m => g -> m Word64 -- | uniformShortByteString n g generates a ShortByteString -- of length n filled with pseudo-random bytes. -- | Deprecated: In favor of uniformShortByteStringM uniformShortByteString :: StatefulGen g m => Int -> g -> m ShortByteString -- | 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: -- --
-- overwriteGen mg fg >> freezeGen mg = pure fg ---- --
-- overwriteGen mg fg = modifyGen mg (const ((), fg) ---- --
-- freezeGen mg = modifyGen mg (fg -> (fg, fg)) --class StatefulGen (MutableGen f m) m => FrozenGen f m where { -- | Represents the state of the pseudo-random number generator for use -- with thawGen and freezeGen. type MutableGen f m = (g :: Type) | g -> f; } -- | Saves the state of the pseudo-random number generator as a frozen -- seed. freezeGen :: FrozenGen f m => MutableGen f m -> m f -- | Apply a pure function to the frozen pseudo-random number generator. modifyGen :: FrozenGen f m => MutableGen f m -> (f -> (a, f)) -> m a -- | Overwrite contents of the mutable pseudo-random number generator with -- the supplied frozen one overwriteGen :: FrozenGen f m => MutableGen f m -> f -> m () -- | 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 -- --
-- traverse thawGen fgs >>= traverse freezeGen = pure fgs --class FrozenGen f m => ThawedGen f m -- | Create a new mutable pseudo-random number generator from its frozen -- state. thawGen :: ThawedGen f m => f -> m (MutableGen f m) -- | Runs a mutable pseudo-random number generator from its -- FrozenGen state. -- --
-- >>> 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}})
--
withMutableGen :: ThawedGen f m => f -> (MutableGen f m -> m a) -> m (a, f)
-- | Same as withMutableGen, but only returns the generated value.
--
-- -- >>> import System.Random.Stateful -- -- >>> let pureGen = mkStdGen 137 -- -- >>> withMutableGen_ (IOGen pureGen) (uniformRM (1 :: Int, 6 :: Int)) -- 4 --withMutableGen_ :: ThawedGen f m => f -> (MutableGen f m -> m a) -> m a -- | Just like withMutableGen, except uses a Seed instead of -- a frozen generator. -- --
-- >>> import Data.ByteString as BS (readFile, writeFile, unpack)
--
-- >>> :seti -XOverloadedStrings
--
-- >>> let reportSeed fp = print . ("Seed: " <>) . show . BS.unpack =<< BS.readFile fp
--
--
-- Given a file path, write an StdGen seed into the file:
--
-- -- >>> :seti -XFlexibleContexts -XScopedTypeVariables -- -- >>> let writeInitSeed fp = BS.writeFile fp (unSeedToByteString (toSeed (mkStdGen 2025))) ---- -- Apply a StatefulGen monadic action that uses IOGen -- StdGen, restored from the seed in the given path: -- --
-- >>> let withMutableSeedFile fp action = withSeedFile fp (\(seed :: Seed (IOGen StdGen)) -> withSeedMutableGen seed action) ---- -- Given a path and an action initialize the seed file and apply the -- action using that seed: -- --
-- >>> let withInitSeedFile fp action = writeInitSeed fp *> reportSeed fp *> withMutableSeedFile fp action <* reportSeed fp ---- -- For the sake of example we will use a temporary directory for storing -- the seed. Here we report the contents of the seed file before and -- after we shuffle a list: -- --
-- >>> import UnliftIO.Temporary (withSystemTempDirectory) -- -- >>> withSystemTempDirectory "random" (\fp -> withInitSeedFile (fp ++ "/seed.bin") (uniformShuffleListM [1..10])) -- "Seed: [183,178,143,77,132,163,109,14,157,105,82,99,148,82,109,173]" -- "Seed: [60,105,117,203,187,138,69,39,157,105,82,99,148,82,109,173]" -- [7,5,4,3,1,8,10,6,9,2] --withSeedMutableGen :: (SeedGen g, ThawedGen g m) => Seed g -> (MutableGen g m -> m a) -> m (a, Seed g) -- | Just like withSeedMutableGen, except it doesn't return the -- final generator, only the resulting value. This is slightly more -- efficient, since it doesn't incur overhead from freezeing the mutable -- generator withSeedMutableGen_ :: (SeedGen g, ThawedGen g m) => Seed g -> (MutableGen g m -> m a) -> m a -- | Generates a pseudo-random value using monadic interface and -- Random instance. -- --
-- >>> import System.Random.Stateful -- -- >>> let pureGen = mkStdGen 139 -- -- >>> g <- newIOGenM pureGen -- -- >>> randomM g :: IO Double -- 0.33775117339631733 ---- -- You can use type applications to disambiguate the type of the -- generated numbers: -- --
-- >>> :seti -XTypeApplications -- -- >>> randomM @Double g -- 0.9156875994165681 --randomM :: forall a g m. (Random a, RandomGen g, FrozenGen g m) => MutableGen g m -> m a -- | Generates a pseudo-random value using monadic interface and -- Random instance. -- --
-- >>> import System.Random.Stateful -- -- >>> let pureGen = mkStdGen 137 -- -- >>> g <- newIOGenM pureGen -- -- >>> randomRM (1, 100) g :: IO Int -- 52 ---- -- You can use type applications to disambiguate the type of the -- generated numbers: -- --
-- >>> :seti -XTypeApplications -- -- >>> randomRM @Int (1, 100) g -- 2 --randomRM :: forall a g m. (Random a, RandomGen g, FrozenGen g m) => (a, a) -> MutableGen g m -> m a -- | 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. splitGenM :: (SplitGen f, FrozenGen f m) => MutableGen f m -> m f -- | Splits a pseudo-random number generator into two. Overwrites the -- mutable wrapper with one of the resulting generators and returns the -- other as a new mutable generator. splitMutableGenM :: (SplitGen f, ThawedGen f m) => MutableGen f m -> m (MutableGen f m) -- | Interface to operations on RandomGen wrappers like -- IOGenM and StateGenM. -- | Deprecated: In favor of FrozenGen class (RandomGen r, StatefulGen g m) => RandomGenM g r m | g -> r -- | Deprecated: In favor of modifyGen applyRandomGenM :: RandomGenM g r m => (r -> (a, r)) -> g -> m a -- | Wrapper for pure state gen, which acts as an immutable seed for the -- corresponding stateful generator StateGenM newtype StateGen g StateGen :: g -> StateGen g [unStateGen] :: StateGen g -> g -- | Opaque data type that carries the type of a pure pseudo-random number -- generator. data StateGenM g StateGenM :: StateGenM g -- | Runs a monadic generating action in the State monad using a -- pure pseudo-random number generator. -- --
-- >>> import System.Random.Stateful
--
-- >>> let pureGen = mkStdGen 137
--
-- >>> runStateGen pureGen randomM :: (Int, StdGen)
-- (7879794327570578227,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
runStateGen :: 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. Returns only the resulting
-- pseudo-random value.
--
-- -- >>> import System.Random.Stateful -- -- >>> let pureGen = mkStdGen 137 -- -- >>> runStateGen_ pureGen randomM :: Int -- 7879794327570578227 --runStateGen_ :: RandomGen g => g -> (StateGenM g -> State g a) -> a -- | Runs a monadic generating action in the StateT monad using a -- pure pseudo-random number generator. -- --
-- >>> import System.Random.Stateful
--
-- >>> let pureGen = mkStdGen 137
--
-- >>> runStateGenT pureGen randomM :: IO (Int, StdGen)
-- (7879794327570578227,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
runStateGenT :: RandomGen g => g -> (StateGenM g -> StateT g m a) -> m (a, g)
-- | Runs a monadic generating action in the StateT monad using a
-- pure pseudo-random number generator. Returns only the resulting
-- pseudo-random value.
--
-- -- >>> import System.Random.Stateful -- -- >>> let pureGen = mkStdGen 137 -- -- >>> runStateGenT_ pureGen randomM :: IO Int -- 7879794327570578227 --runStateGenT_ :: (RandomGen g, Functor f) => g -> (StateGenM g -> StateT g f a) -> f a -- | Runs a monadic generating action in the ST monad using a pure -- pseudo-random number generator. runStateGenST :: RandomGen g => g -> (forall s. StateGenM g -> StateT g (ST s) a) -> (a, g) -- | Runs a monadic generating action in the ST monad using a pure -- pseudo-random number generator. Same as runStateGenST, but -- discards the resulting generator. runStateGenST_ :: RandomGen g => g -> (forall s. StateGenM g -> StateT g (ST s) a) -> a -- | Frozen version of mutable AtomicGenM generator newtype AtomicGen g AtomicGen :: g -> AtomicGen g [unAtomicGen] :: AtomicGen g -> g -- | Wraps an IORef that holds a pure pseudo-random number -- generator. All operations are performed atomically. -- --
-- >>> import System.Random.Stateful -- -- >>> let pureGen = mkStdGen 137 -- -- >>> g <- newAtomicGenM pureGen -- -- >>> applyAtomicGen random g :: IO Int -- 7879794327570578227 --applyAtomicGen :: MonadIO m => (g -> (a, g)) -> AtomicGenM g -> m a -- | Global mutable standard pseudo-random number generator. This is the -- same generator that was historically used by randomIO and -- randomRIO functions. -- --
-- >>> import Control.Monad (replicateM)
--
-- >>> replicateM 10 (uniformRM ('a', 'z') globalStdGen)
-- "tdzxhyfvgr"
--
globalStdGen :: AtomicGenM StdGen
-- | Frozen version of mutable IOGenM generator
newtype IOGen g
IOGen :: g -> IOGen g
[unIOGen] :: IOGen g -> g
-- | Wraps an IORef that holds a pure pseudo-random number
-- generator.
--
-- -- >>> 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 --newtype IOGenM g IOGenM :: IORef g -> IOGenM g [unIOGenM] :: IOGenM g -> IORef g -- | Creates a new IOGenM. newIOGenM :: MonadIO m => g -> m (IOGenM g) -- | Applies a pure operation to the wrapped pseudo-random number -- generator. -- --
-- >>> import System.Random.Stateful -- -- >>> let pureGen = mkStdGen 137 -- -- >>> g <- newIOGenM pureGen -- -- >>> applyIOGen random g :: IO Int -- 7879794327570578227 --applyIOGen :: MonadIO m => (g -> (a, g)) -> IOGenM g -> m a -- | Frozen version of mutable STGenM generator newtype STGen g STGen :: g -> STGen g [unSTGen] :: STGen g -> g -- | Wraps an STRef that holds a pure pseudo-random number -- generator. -- --
-- >>> import System.Random.Stateful
--
-- >>> let pureGen = mkStdGen 137
--
-- >>> (runSTGen pureGen (\g -> applySTGen random g)) :: (Int, StdGen)
-- (7879794327570578227,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
applySTGen :: (g -> (a, g)) -> STGenM g s -> ST s a
-- | Runs a monadic generating action in the ST monad using a pure
-- pseudo-random number generator.
--
--
-- >>> import System.Random.Stateful
--
-- >>> let pureGen = mkStdGen 137
--
-- >>> (runSTGen pureGen (\g -> applySTGen random g)) :: (Int, StdGen)
-- (7879794327570578227,StdGen {unStdGen = SMGen 11285859549637045894 7641485672361121627})
--
runSTGen :: RandomGen g => g -> (forall s. STGenM g s -> ST s a) -> (a, g)
-- | Runs a monadic generating action in the ST monad using a pure
-- pseudo-random number generator. Returns only the resulting
-- pseudo-random value.
--
-- -- >>> import System.Random.Stateful -- -- >>> let pureGen = mkStdGen 137 -- -- >>> (runSTGen_ pureGen (\g -> applySTGen random g)) :: Int -- 7879794327570578227 --runSTGen_ :: RandomGen g => g -> (forall s. STGenM g s -> ST s a) -> a -- | Frozen version of mutable TGenM generator newtype TGen g TGen :: g -> TGen g [unTGen] :: TGen g -> g -- | Wraps a TVar that holds a pure pseudo-random number generator. newtype TGenM g TGenM :: TVar g -> TGenM g [unTGenM] :: TGenM g -> TVar g -- | Creates a new TGenM in STM. newTGenM :: g -> STM (TGenM g) -- | Creates a new TGenM in IO. newTGenMIO :: MonadIO m => g -> m (TGenM g) -- | Applies a pure operation to the wrapped pseudo-random number -- generator. -- --
-- >>> 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 --applyTGen :: (g -> (a, g)) -> TGenM g -> STM a -- | The class of types for which a uniformly distributed value can be -- drawn from all possible values of the type. class Uniform a -- | Generates a value uniformly distributed over all possible values of -- that type. -- -- There is a default implementation via Generic: -- --
-- >>> :seti -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] --uniformM :: (Uniform a, 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: -- --
-- >>> :seti -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] --uniformM :: (Uniform a, StatefulGen g m, Generic a, GUniform (Rep a)) => g -> 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. -- --
-- >>> :seti -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] --uniformViaFiniteM :: (StatefulGen g m, Generic a, GFinite (Rep a)) => g -> m a -- | The class of types for which a uniformly distributed value can be -- drawn from a range. class UniformRange a -- | Generates a value uniformly distributed over the provided range, which -- is interpreted as inclusive in the lower and upper bound. -- --
-- 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: -- --
-- >>> :seti -XDeriveGeneric -XDeriveAnyClass -- -- >>> import GHC.Generics (Generic) -- -- >>> import Data.Word (Word8) -- -- >>> import Control.Monad (replicateM) -- -- >>> import System.Random.Stateful -- -- >>> gen <- 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] --uniformRM :: (UniformRange a, StatefulGen g m) => (a, a) -> g -> m a -- | 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 isInRange :: UniformRange a => (a, a) -> a -> Bool -- | Generates a value uniformly distributed over the provided range, which -- is interpreted as inclusive in the lower and upper bound. -- --
-- 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: -- --
-- >>> :seti -XDeriveGeneric -XDeriveAnyClass -- -- >>> import GHC.Generics (Generic) -- -- >>> import Data.Word (Word8) -- -- >>> import Control.Monad (replicateM) -- -- >>> import System.Random.Stateful -- -- >>> gen <- 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] --uniformRM :: (UniformRange a, StatefulGen g m, Generic a, GUniformRange (Rep a)) => (a, a) -> g -> m a -- | 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 isInRange :: (UniformRange a, Generic a, GUniformRange (Rep a)) => (a, a) -> a -> Bool -- | Utilize Ord instance to decide if a value is within the range. -- Designed to be used for implementing isInRange isInRangeOrd :: Ord a => (a, a) -> a -> Bool -- | Utilize Enum instance to decide if a value is within the range. -- Designed to be used for implementing isInRange isInRangeEnum :: Enum a => (a, a) -> a -> Bool -- | Generates a list of pseudo-random values. -- --
-- >>> 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] --uniformListM :: (StatefulGen g m, Uniform a) => Int -> g -> m [a] -- | Generates a list of pseudo-random values in a specified range. -- --
-- >>> import System.Random.Stateful -- -- >>> let pureGen = mkStdGen 137 -- -- >>> g <- newIOGenM pureGen -- -- >>> uniformListRM 10 (20, 30) g :: IO [Int] -- [23,21,28,25,28,28,26,25,29,27] --uniformListRM :: (StatefulGen g m, UniformRange a) => Int -> (a, a) -> g -> m [a] -- | Shuffle elements of a list in a uniformly random order. -- --
-- >>> import System.Random.Stateful -- -- >>> runStateGen_ (mkStdGen 127) $ uniformShuffleListM "ELVIS" -- "LIVES" --uniformShuffleListM :: StatefulGen g m => [a] -> g -> m [a] -- | uniformByteArrayM n g generates a ByteArray of length -- n filled with pseudo-random bytes. uniformByteArrayM :: StatefulGen g m => Bool -> Int -> g -> m ByteArray -- | Generates a pseudo-random ByteString of the specified size. uniformByteStringM :: StatefulGen g m => Int -> g -> m ByteString -- | uniformShortByteString n g generates a ShortByteString -- of length n filled with pseudo-random bytes. uniformShortByteStringM :: StatefulGen g m => Int -> g -> m ShortByteString -- | Using an ST action that generates 8 bytes at a time fill in a -- new ByteArray in architecture agnostic manner. fillByteArrayST :: Bool -> Int -> ST s Word64 -> ST s ByteArray -- | Efficiently fills in a new ShortByteString in a platform -- independent manner. -- | Deprecated: In favor of fillByteArrayST genShortByteStringIO :: Int -> IO Word64 -> IO ShortByteString -- | Same as genShortByteStringIO, but runs in ST. -- | Deprecated: In favor of fillByteArrayST, since -- uniformShortByteString, which it was used for, was also -- deprecated genShortByteStringST :: Int -> ST s Word64 -> ST s ShortByteString -- | Efficiently generates a sequence of pseudo-random bytes in a platform -- independent manner. defaultUnsafeUniformFillMutableByteArray :: RandomGen g => MutableByteArray s -> Int -> Int -> g -> ST s g -- | Generates uniformly distributed Double in the range -- <math>. Numbers are generated by generating uniform -- Word64 and dividing it by <math>. It's used to implement -- UniformRange instance for Double. uniformDouble01M :: forall g m. StatefulGen g m => g -> m Double -- | Generates uniformly distributed Double in the range -- <math>. Number is generated as <math>. Constant is 1/2 of -- smallest nonzero value which could be generated by -- uniformDouble01M. uniformDoublePositive01M :: forall g m. StatefulGen g m => g -> m Double -- | Generates uniformly distributed Float in the range -- <math>. Numbers are generated by generating uniform -- Word32 and dividing it by <math>. It's used to implement -- UniformRange instance for Float. uniformFloat01M :: forall g m. StatefulGen g m => g -> m Float -- | Generates uniformly distributed Float in the range -- <math>. Number is generated as <math>. Constant is 1/2 of -- smallest nonzero value which could be generated by -- uniformFloat01M. uniformFloatPositive01M :: forall g m. StatefulGen g m => g -> m Float -- | 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 --uniformEnumM :: forall a g m. (Enum a, Bounded a, StatefulGen g m) => 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) --uniformEnumRM :: forall a g m. (Enum a, StatefulGen g m) => (a, a) -> g -> m a -- | Architecture specific Word generation in the specified lower -- range uniformWordR :: StatefulGen g m => Word -> g -> m Word -- | This is the function that is used to scale a floating point value from -- random word range to the custom [low, high] range. scaleFloating :: forall a w. (RealFloat a, Integral w, Bounded w, FiniteBits w) => a -> a -> w -> a instance Control.DeepSeq.NFData g => Control.DeepSeq.NFData (System.Random.Stateful.AtomicGen g) instance Foreign.Storable.Storable g => Foreign.Storable.Storable (System.Random.Stateful.AtomicGen g) instance System.Random.Internal.SplitGen g => System.Random.Internal.SplitGen (System.Random.Stateful.AtomicGen g) instance System.Random.Internal.RandomGen g => System.Random.Internal.RandomGen (System.Random.Stateful.AtomicGen g) instance GHC.Show.Show g => GHC.Show.Show (System.Random.Stateful.AtomicGen g) instance GHC.Classes.Ord g => GHC.Classes.Ord (System.Random.Stateful.AtomicGen g) instance GHC.Classes.Eq g => GHC.Classes.Eq (System.Random.Stateful.AtomicGen g) instance Control.DeepSeq.NFData g => Control.DeepSeq.NFData (System.Random.Stateful.IOGen g) instance Foreign.Storable.Storable g => Foreign.Storable.Storable (System.Random.Stateful.IOGen g) instance System.Random.Internal.SplitGen g => System.Random.Internal.SplitGen (System.Random.Stateful.IOGen g) instance System.Random.Internal.RandomGen g => System.Random.Internal.RandomGen (System.Random.Stateful.IOGen g) instance GHC.Show.Show g => GHC.Show.Show (System.Random.Stateful.IOGen g) instance GHC.Classes.Ord g => GHC.Classes.Ord (System.Random.Stateful.IOGen g) instance GHC.Classes.Eq g => GHC.Classes.Eq (System.Random.Stateful.IOGen g) instance Control.DeepSeq.NFData g => Control.DeepSeq.NFData (System.Random.Stateful.STGen g) instance Foreign.Storable.Storable g => Foreign.Storable.Storable (System.Random.Stateful.STGen g) instance System.Random.Internal.SplitGen g => System.Random.Internal.SplitGen (System.Random.Stateful.STGen g) instance System.Random.Internal.RandomGen g => System.Random.Internal.RandomGen (System.Random.Stateful.STGen g) instance GHC.Show.Show g => GHC.Show.Show (System.Random.Stateful.STGen g) instance GHC.Classes.Ord g => GHC.Classes.Ord (System.Random.Stateful.STGen g) instance GHC.Classes.Eq g => GHC.Classes.Eq (System.Random.Stateful.STGen g) instance Control.DeepSeq.NFData g => Control.DeepSeq.NFData (System.Random.Stateful.TGen g) instance Foreign.Storable.Storable g => Foreign.Storable.Storable (System.Random.Stateful.TGen g) instance System.Random.Internal.SplitGen g => System.Random.Internal.SplitGen (System.Random.Stateful.TGen g) instance System.Random.Internal.RandomGen g => System.Random.Internal.RandomGen (System.Random.Stateful.TGen g) instance GHC.Show.Show g => GHC.Show.Show (System.Random.Stateful.TGen g) instance GHC.Classes.Ord g => GHC.Classes.Ord (System.Random.Stateful.TGen g) instance GHC.Classes.Eq g => GHC.Classes.Eq (System.Random.Stateful.TGen g) instance System.Random.Seed.SeedGen g => System.Random.Seed.SeedGen (System.Random.Stateful.TGen g) instance System.Random.Internal.RandomGen g => System.Random.Internal.FrozenGen (System.Random.Stateful.TGen g) GHC.Conc.Sync.STM instance System.Random.Internal.RandomGen g => System.Random.Internal.ThawedGen (System.Random.Stateful.TGen g) GHC.Conc.Sync.STM instance System.Random.Internal.RandomGen r => System.Random.Stateful.RandomGenM (System.Random.Stateful.TGenM r) r GHC.Conc.Sync.STM instance System.Random.Internal.RandomGen g => System.Random.Internal.StatefulGen (System.Random.Stateful.TGenM g) GHC.Conc.Sync.STM instance System.Random.Seed.SeedGen g => System.Random.Seed.SeedGen (System.Random.Stateful.STGen g) instance System.Random.Internal.RandomGen g => System.Random.Internal.FrozenGen (System.Random.Stateful.STGen g) (GHC.ST.ST s) instance System.Random.Internal.RandomGen g => System.Random.Internal.ThawedGen (System.Random.Stateful.STGen g) (GHC.ST.ST s) instance System.Random.Internal.RandomGen r => System.Random.Stateful.RandomGenM (System.Random.Stateful.STGenM r s) r (GHC.ST.ST s) instance System.Random.Internal.RandomGen g => System.Random.Internal.StatefulGen (System.Random.Stateful.STGenM g s) (GHC.ST.ST s) instance System.Random.Seed.SeedGen g => System.Random.Seed.SeedGen (System.Random.Stateful.IOGen g) instance (System.Random.Internal.RandomGen g, Control.Monad.IO.Class.MonadIO m) => System.Random.Internal.FrozenGen (System.Random.Stateful.IOGen g) m instance (System.Random.Internal.RandomGen g, Control.Monad.IO.Class.MonadIO m) => System.Random.Internal.ThawedGen (System.Random.Stateful.IOGen g) m instance (System.Random.Internal.RandomGen r, Control.Monad.IO.Class.MonadIO m) => System.Random.Stateful.RandomGenM (System.Random.Stateful.IOGenM r) r m instance (System.Random.Internal.RandomGen g, Control.Monad.IO.Class.MonadIO m) => System.Random.Internal.StatefulGen (System.Random.Stateful.IOGenM g) m instance System.Random.Seed.SeedGen g => System.Random.Seed.SeedGen (System.Random.Stateful.AtomicGen g) instance (System.Random.Internal.RandomGen g, Control.Monad.IO.Class.MonadIO m) => System.Random.Internal.FrozenGen (System.Random.Stateful.AtomicGen g) m instance (System.Random.Internal.RandomGen g, Control.Monad.IO.Class.MonadIO m) => System.Random.Internal.ThawedGen (System.Random.Stateful.AtomicGen g) m instance (System.Random.Internal.RandomGen r, Control.Monad.IO.Class.MonadIO m) => System.Random.Stateful.RandomGenM (System.Random.Stateful.AtomicGenM r) r m instance (System.Random.Internal.RandomGen g, Control.Monad.IO.Class.MonadIO m) => System.Random.Internal.StatefulGen (System.Random.Stateful.AtomicGenM g) m instance (System.Random.Internal.RandomGen r, Control.Monad.State.Class.MonadState r m) => System.Random.Stateful.RandomGenM (System.Random.Internal.StateGenM r) r m