From 19d26059556fa2125d59c90808bda380a0a03f80 Mon Sep 17 00:00:00 2001 From: Alexey Kuleshevich Date: Thu, 7 May 2020 15:28:24 +0300 Subject: [PATCH] Refactor naming of mutable generators and switch to `TypeFamilyDependencies` for `Frozen` --- System/Random.hs | 20 ++--- System/Random/Internal.hs | 58 +++++++------- System/Random/Monad.hs | 155 +++++++++++++++++++++----------------- stack-old.yaml | 2 - test/Spec/Range.hs | 4 +- test/Spec/Run.hs | 2 +- 6 files changed, 128 insertions(+), 113 deletions(-) diff --git a/System/Random.hs b/System/Random.hs index 9256f5575..bff4145f7 100644 --- a/System/Random.hs +++ b/System/Random.hs @@ -101,7 +101,7 @@ import qualified System.Random.SplitMix as SM -- rollsM n = replicateM n . uniformRM (1, 6) -- pureGen = mkStdGen 137 -- in --- runGenState_ pureGen (rollsM 10) :: [Word8] +-- runStateGen_ pureGen (rollsM 10) :: [Word8] -- :} -- [1,2,6,6,5,1,4,6,5,4] @@ -134,7 +134,7 @@ import qualified System.Random.SplitMix as SM -- -- @since 1.2 uniform :: (RandomGen g, Uniform a) => g -> (a, g) -uniform g = runGenState g uniformM +uniform g = runStateGen g uniformM -- | Generates a value uniformly distributed over the provided range, which -- is interpreted as inclusive in the lower and upper bound. @@ -153,14 +153,14 @@ uniform g = runGenState g uniformM -- -- @since 1.2 uniformR :: (RandomGen g, UniformRange a) => (a, a) -> g -> (a, g) -uniformR r g = runGenState g (uniformRM r) +uniformR r g = runStateGen g (uniformRM r) -- | Generates a 'ByteString' of the specified size using a pure pseudo-random -- number generator. See 'uniformByteString' for the monadic version. -- -- @since 1.2 genByteString :: RandomGen g => Int -> g -> (ByteString, g) -genByteString n g = runPureGenST g (uniformByteString n) +genByteString n g = runStateGenST g (uniformByteString n) {-# INLINE genByteString #-} -- | The class of types for which uniformly distributed values can be @@ -180,7 +180,7 @@ class Random a where {-# INLINE randomR #-} randomR :: RandomGen g => (a, a) -> g -> (a, g) default randomR :: (RandomGen g, UniformRange a) => (a, a) -> g -> (a, g) - randomR r g = runGenState g (uniformRM r) + randomR r g = runStateGen g (uniformRM r) -- | The same as 'randomR', but using a default range determined by the type: -- @@ -194,7 +194,7 @@ class Random a where {-# INLINE random #-} random :: RandomGen g => g -> (a, g) default random :: (RandomGen g, Uniform a) => g -> (a, g) - random g = runGenState g uniformM + random g = runStateGen g uniformM -- | Plural variant of 'randomR', producing an infinite list of -- pseudo-random values instead of returning a new generator. @@ -264,11 +264,11 @@ instance Random CDouble where instance Random Char instance Random Bool instance Random Double where - randomR r g = runGenState g (uniformRM r) - random g = runGenState g (uniformRM (0, 1)) + randomR r g = runStateGen g (uniformRM r) + random g = runStateGen g (uniformRM (0, 1)) instance Random Float where - randomR r g = runGenState g (uniformRM r) - random g = runGenState g (uniformRM (0, 1)) + randomR r g = runStateGen g (uniformRM r) + random g = runStateGen g (uniformRM (0, 1)) ------------------------------------------------------------------------------- -- Global pseudo-random number generator diff --git a/System/Random/Internal.hs b/System/Random/Internal.hs index f88b08f6d..5ba916b8f 100644 --- a/System/Random/Internal.hs +++ b/System/Random/Internal.hs @@ -11,6 +11,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UnliftedFFITypes #-} @@ -29,7 +30,6 @@ module System.Random.Internal (-- * Pure and monadic pseudo-random number generator interfaces RandomGen(..) , MonadRandom(..) - , Frozen(..) -- ** Standard pseudo-random number generator , StdGen @@ -37,13 +37,14 @@ module System.Random.Internal -- * Monadic adapters for pure pseudo-random number generators -- ** Pure adapter - , PureGen + , StateGen(..) + , StateGenM(..) , splitGen - , runGenState - , runGenState_ - , runGenStateT - , runGenStateT_ - , runPureGenST + , runStateGen + , runStateGen_ + , runStateGenT + , runStateGenT_ + , runStateGenST -- * Pseudo-random values of various types , Uniform(..) @@ -92,7 +93,7 @@ class RandomGen g where -- [here](https://alexey.kuleshevi.ch/blog/2019/12/21/random-benchmarks) for -- more details. It is thus deprecated. next :: g -> (Int, g) - next g = runGenState g (uniformRM (genRange g)) + next g = runStateGen g (uniformRM (genRange g)) -- | Returns a 'Word8' that is uniformly distributed over the entire 'Word8' -- range. @@ -134,14 +135,14 @@ class RandomGen g where -- -- @since 1.2 genWord32R :: Word32 -> g -> (Word32, g) - genWord32R m g = runGenState g (unbiasedWordMult32 m) + genWord32R m g = runStateGen g (unbiasedWordMult32 m) -- | @genWord64R upperBound g@ returns a 'Word64' that is uniformly -- distributed over the range @[0, upperBound]@. -- -- @since 1.2 genWord64R :: Word64 -> g -> (Word64, g) - genWord64R m g = runGenState g (unsignedBitmaskWithRejectionM uniformWord64 m) + genWord64R m g = runStateGen g (unsignedBitmaskWithRejectionM uniformWord64 m) -- | @genShortByteString n g@ returns a 'ShortByteString' of length @n@ -- filled with pseudo-random bytes. @@ -149,7 +150,7 @@ class RandomGen g where -- @since 1.2 genShortByteString :: Int -> g -> (ShortByteString, g) genShortByteString n g = - unsafePerformIO $ runGenStateT g (genShortByteStringIO n . uniformWord64) + unsafePerformIO $ runStateGenT g (genShortByteStringIO n . uniformWord64) {-# INLINE genShortByteString #-} -- | Yields the range of values returned by 'next'. @@ -179,7 +180,7 @@ class Monad m => MonadRandom g s m | g m -> s where -- 'thawGen' and 'freezeGen'. -- -- @since 1.2 - data Frozen g :: * + type Frozen g = (f :: *) | f -> g {-# MINIMAL freezeGen,thawGen,(uniformWord32|uniformWord64) #-} -- | Restores the pseudo-random number generator from its 'Frozen' @@ -339,12 +340,13 @@ uniformByteString n g = do -- generator. -- -- @since 1.2 -data PureGen g s = PureGenI +data StateGenM g s = StateGenM +newtype StateGen g = StateGen g -instance (RandomGen g, MonadState g m) => MonadRandom (PureGen g) g m where - newtype Frozen (PureGen g) = PureGen g - thawGen (PureGen g) = PureGenI <$ put g - freezeGen _ = fmap PureGen get +instance (RandomGen g, MonadState g m) => MonadRandom (StateGenM g) g m where + type Frozen (StateGenM g) = StateGen g + thawGen (StateGen g) = StateGenM <$ put g + freezeGen _ = fmap StateGen get uniformWord32R r _ = state (genWord32R r) uniformWord64R r _ = state (genWord64R r) uniformWord8 _ = state genWord8 @@ -366,39 +368,39 @@ splitGen = state split -- pseudo-random number generator. -- -- @since 1.2 -runGenState :: RandomGen g => g -> (PureGen g g -> State g a) -> (a, g) -runGenState g f = runState (f PureGenI) g +runStateGen :: RandomGen g => g -> (StateGenM g g -> State g a) -> (a, g) +runStateGen g f = runState (f StateGenM) g -- | Runs a monadic generating action in the `State` monad using a pure -- pseudo-random number generator. Returns only the resulting pseudo-random -- value. -- -- @since 1.2 -runGenState_ :: RandomGen g => g -> (PureGen g g -> State g a) -> a -runGenState_ g = fst . runGenState g +runStateGen_ :: RandomGen g => g -> (StateGenM g g -> State g a) -> a +runStateGen_ g = fst . runStateGen g -- | Runs a monadic generating action in the `StateT` monad using a pure -- pseudo-random number generator. -- -- @since 1.2 -runGenStateT :: RandomGen g => g -> (PureGen g g -> StateT g m a) -> m (a, g) -runGenStateT g f = runStateT (f PureGenI) g +runStateGenT :: RandomGen g => g -> (StateGenM g g -> StateT g m a) -> m (a, g) +runStateGenT g f = runStateT (f StateGenM) g -- | Runs a monadic generating action in the `StateT` monad using a pure -- pseudo-random number generator. Returns only the resulting pseudo-random -- value. -- -- @since 1.2 -runGenStateT_ :: (RandomGen g, Functor f) => g -> (PureGen g g -> StateT g f a) -> f a -runGenStateT_ g = fmap fst . runGenStateT g +runStateGenT_ :: (RandomGen g, Functor f) => g -> (StateGenM g g -> StateT g f a) -> f a +runStateGenT_ g = fmap fst . runStateGenT g -- | Runs a monadic generating action in the `ST` monad using a pure -- pseudo-random number generator. -- -- @since 1.2 -runPureGenST :: RandomGen g => g -> (forall s . PureGen g g -> StateT g (ST s) a) -> (a, g) -runPureGenST g action = runST $ runGenStateT g $ action -{-# INLINE runPureGenST #-} +runStateGenST :: RandomGen g => g -> (forall s . StateGenM g g -> StateT g (ST s) a) -> (a, g) +runStateGenST g action = runST $ runStateGenT g action +{-# INLINE runStateGenST #-} -- | The standard pseudo-random number generator. diff --git a/System/Random/Monad.hs b/System/Random/Monad.hs index 3c98b7db0..dc0110886 100644 --- a/System/Random/Monad.hs +++ b/System/Random/Monad.hs @@ -27,32 +27,35 @@ module System.Random.Monad -- * Pure and monadic pseudo-random number generator interfaces -- $interfaces , MonadRandom(..) - , Frozen(..) , runGenM , runGenM_ , RandomGenM(..) - , splitRandomGenM + , randomM + , randomRM + , splitGenM -- * Monadic adapters for pure pseudo-random number generators -- $monadicadapters -- ** Pure adapter - , PureGen - , splitGen - , genRandom - , runGenState - , runGenState_ - , runGenStateT - , runGenStateT_ - , runPureGenST + , StateGen(..) + , StateGenM(..) + , runStateGen + , runStateGen_ + , runStateGenT + , runStateGenT_ + , runStateGenST -- ** Mutable adapter with atomic operations - , AtomicGen + , AtomicGen(..) + , AtomicGenM(..) , applyAtomicGen -- ** Mutable adapter in 'IO' - , IOGen + , IOGen(..) + , IOGenM(..) , applyIOGen -- ** Mutable adapter in 'ST' - , STGen + , STGen(..) + , STGenM(..) , applySTGen , runSTGen , runSTGen_ @@ -92,7 +95,7 @@ import System.Random.Internal -- [Monadic pseudo-random number generators] 'MonadRandom' is an interface to -- monadic pseudo-random number generators. -- --- [Monadic adapters] 'PureGen', 'AtomicGen', 'IOGen' and 'STGen' turn a +-- [Monadic adapters] 'StateGenM', 'AtomicGenM', 'IOGenM' and 'STGenM' turn a -- 'RandomGen' instance into a 'MonadRandom' instance. -- -- [Drawing from a range] 'UniformRange' is used to generate a value of a @@ -163,23 +166,23 @@ import System.Random.Internal -- $monadicadapters -- -- Pure pseudo-random number generators can be used in monadic code via the --- adapters 'PureGen', 'AtomicGen', 'IOGen' and 'STGen'. +-- adapters 'StateGenM', 'AtomicGenM', 'IOGenM' and 'STGenM'. -- --- * 'PureGen' can be used in any state monad. With strict 'StateT' there is +-- * 'StateGenM' can be used in any state monad. With strict 'StateT' there is -- no performance overhead compared to using the 'RandomGen' instance --- directly. 'PureGen' is /not/ safe to use in the presence of exceptions +-- directly. 'StateGenM' is /not/ safe to use in the presence of exceptions -- and concurrency. -- --- * 'AtomicGen' is safe in the presence of exceptions and concurrency since +-- * 'AtomicGenM' is safe in the presence of exceptions and concurrency since -- it performs all actions atomically. -- --- * 'IOGen' is a wrapper around an 'IORef' that holds a pure generator. --- 'IOGen' is safe in the presence of exceptions, but not concurrency. +-- * 'IOGenM' is a wrapper around an 'IORef' that holds a pure generator. +-- 'IOGenM' is safe in the presence of exceptions, but not concurrency. -- --- * 'STGen' is a wrapper around an 'STRef' that holds a pure generator. --- 'STGen' 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. --- | Interface to operations on 'RandomGen' wrappers like 'IOGen' and 'PureGen'. +-- | Interface to operations on 'RandomGen' wrappers like 'IOGenM' and 'StateGenM'. -- -- @since 1.2 class (RandomGen r, MonadRandom (g r) s m) => RandomGenM g r s m where @@ -189,25 +192,25 @@ class (RandomGen r, MonadRandom (g r) s m) => RandomGenM g r s m where -- wrapper with one of the resulting generators and returns the other. -- -- @since 1.2 -splitRandomGenM :: RandomGenM g r s m => g r s -> m r -splitRandomGenM = applyRandomGenM split +splitGenM :: RandomGenM g r s m => g r s -> m r +splitGenM = applyRandomGenM split -instance (RandomGen r, MonadIO m) => RandomGenM IOGen r RealWorld m where +instance (RandomGen r, MonadIO m) => RandomGenM IOGenM r RealWorld m where applyRandomGenM = applyIOGen -instance (RandomGen r, MonadIO m) => RandomGenM AtomicGen r RealWorld m where +instance (RandomGen r, MonadIO m) => RandomGenM AtomicGenM r RealWorld m where applyRandomGenM = applyAtomicGen -instance (RandomGen r, MonadState r m) => RandomGenM PureGen r r m where +instance (RandomGen r, MonadState r m) => RandomGenM StateGenM r r m where applyRandomGenM f _ = state f -instance RandomGen r => RandomGenM STGen r s (ST s) where +instance RandomGen r => RandomGenM STGenM r s (ST s) where applyRandomGenM = applySTGen -- | Runs a mutable pseudo-random number generator from its 'Frozen' state. -- -- >>> import Data.Int (Int8) --- >>> runGenM (IOGen (mkStdGen 217)) (`uniformListM` 5) :: IO ([Int8], Frozen (IOGen StdGen)) +-- >>> runGenM (IOGen (mkStdGen 217)) (`uniformListM` 5) :: IO ([Int8], IOGen StdGen) -- ([-74,37,-50,-2,3],IOGen {unIOGen = SMGen 4273268533320920145 15251669095119325999}) -- -- @since 1.2 @@ -230,27 +233,35 @@ runGenM_ fg action = fst <$> runGenM fg action uniformListM :: (MonadRandom g s m, Uniform a) => g s -> Int -> m [a] uniformListM gen n = replicateM n (uniformM gen) --- | Generates a pseudo-random value in a state monad. +-- | Generates a pseudo-random value using monadic interface and `Random` instance. -- -- @since 1.2 -genRandom :: (RandomGen g, Random a, MonadState g m) => PureGen g g -> m a -genRandom _ = state random +randomM :: (RandomGenM g r s m, Random a) => g r s -> m a +randomM = applyRandomGenM random + +-- | Generates a pseudo-random value using monadic interface and `Random` instance. +-- +-- @since 1.2 +randomRM :: (RandomGenM g r s m, Random a) => (a, a) -> g r s -> m a +randomRM r = applyRandomGenM (randomR r) -- | Wraps an 'IORef' that holds a pure pseudo-random number generator. All -- operations are performed atomically. -- --- * 'AtomicGen' is safe in the presence of exceptions and concurrency. --- * 'AtomicGen' is the slowest of the monadic adapters due to the overhead +-- * '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 -newtype AtomicGen g s = AtomicGenI (IORef g) +newtype AtomicGenM g s = AtomicGenM { unAtomicGenM :: IORef g} -instance (RandomGen g, MonadIO m) => MonadRandom (AtomicGen g) RealWorld m where - newtype Frozen (AtomicGen g) = AtomicGen { unAtomicGen :: g } +newtype AtomicGen g = AtomicGen { unAtomicGen :: g } deriving (Eq, Show, Read) - thawGen (AtomicGen g) = fmap AtomicGenI (liftIO $ newIORef g) - freezeGen (AtomicGenI gVar) = fmap AtomicGen (liftIO $ readIORef gVar) + +instance (RandomGen g, MonadIO m) => MonadRandom (AtomicGenM g) RealWorld m where + type Frozen (AtomicGenM g) = AtomicGen g + thawGen (AtomicGen g) = fmap AtomicGenM (liftIO $ newIORef g) + freezeGen (AtomicGenM gVar) = fmap AtomicGen (liftIO $ readIORef gVar) uniformWord32R r = applyAtomicGen (genWord32R r) {-# INLINE uniformWord32R #-} uniformWord64R r = applyAtomicGen (genWord64R r) @@ -269,8 +280,8 @@ instance (RandomGen g, MonadIO m) => MonadRandom (AtomicGen g) RealWorld m where -- generator. -- -- @since 1.2 -applyAtomicGen :: MonadIO m => (g -> (a, g)) -> AtomicGen g RealWorld -> m a -applyAtomicGen op (AtomicGenI gVar) = +applyAtomicGen :: MonadIO m => (g -> (a, g)) -> AtomicGenM g RealWorld -> m a +applyAtomicGen op (AtomicGenM gVar) = liftIO $ atomicModifyIORef' gVar $ \g -> case op g of (a, g') -> (g', a) @@ -278,10 +289,10 @@ applyAtomicGen op (AtomicGenI gVar) = -- | Wraps an 'IORef' that holds a pure pseudo-random number generator. -- --- * 'IOGen' is safe in the presence of exceptions, but not concurrency. --- * 'IOGen' is slower than 'PureGen' due to the extra pointer indirection. --- * 'IOGen' is faster than 'AtomicGen' since the 'IORef' operations used by --- 'IOGen' are not atomic. +-- * '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: -- @@ -294,13 +305,15 @@ applyAtomicGen op (AtomicGenI gVar) = -- >>> runGenM_ (IOGen (mkStdGen 1729)) ioGen -- -- @since 1.2 -newtype IOGen g s = IOGenI (IORef g) +newtype IOGenM g s = IOGenM { unIOGenM :: IORef g } -instance (RandomGen g, MonadIO m) => MonadRandom (IOGen g) RealWorld m where - newtype Frozen (IOGen g) = IOGen { unIOGen :: g } +newtype IOGen g = IOGen { unIOGen :: g } deriving (Eq, Show, Read) - thawGen (IOGen g) = fmap IOGenI (liftIO $ newIORef g) - freezeGen (IOGenI gVar) = fmap IOGen (liftIO $ readIORef gVar) + +instance (RandomGen g, MonadIO m) => MonadRandom (IOGenM g) RealWorld m where + type Frozen (IOGenM g) = IOGen g + thawGen (IOGen g) = fmap IOGenM (liftIO $ newIORef g) + freezeGen (IOGenM gVar) = fmap IOGen (liftIO $ readIORef gVar) uniformWord32R r = applyIOGen (genWord32R r) {-# INLINE uniformWord32R #-} uniformWord64R r = applyIOGen (genWord64R r) @@ -318,8 +331,8 @@ instance (RandomGen g, MonadIO m) => MonadRandom (IOGen g) RealWorld m where -- | Applies a pure operation to the wrapped pseudo-random number generator. -- -- @since 1.2 -applyIOGen :: MonadIO m => (g -> (a, g)) -> IOGen g RealWorld -> m a -applyIOGen f (IOGenI ref) = liftIO $ do +applyIOGen :: MonadIO m => (g -> (a, g)) -> IOGenM g RealWorld -> m a +applyIOGen f (IOGenM ref) = liftIO $ do g <- readIORef ref case f g of (!a, !g') -> a <$ writeIORef ref g' @@ -327,17 +340,19 @@ applyIOGen f (IOGenI ref) = liftIO $ do -- | Wraps an 'STRef' that holds a pure pseudo-random number generator. -- --- * 'STGen' is safe in the presence of exceptions, but not concurrency. --- * 'STGen' is slower than 'PureGen' due to the extra pointer indirection. +-- * '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 -newtype STGen g s = STGenI (STRef s g) +newtype STGenM g s = STGenM { unSTGenM :: STRef s g } -instance RandomGen g => MonadRandom (STGen g) s (ST s) where - newtype Frozen (STGen g) = STGen { unSTGen :: g } +newtype STGen g = STGen { unSTGen :: g } deriving (Eq, Show, Read) - thawGen (STGen g) = fmap STGenI (newSTRef g) - freezeGen (STGenI gVar) = fmap STGen (readSTRef gVar) + +instance RandomGen g => MonadRandom (STGenM g) s (ST s) where + type Frozen (STGenM g) = STGen g + thawGen (STGen g) = fmap STGenM (newSTRef g) + freezeGen (STGenM gVar) = fmap STGen (readSTRef gVar) uniformWord32R r = applySTGen (genWord32R r) {-# INLINE uniformWord32R #-} uniformWord64R r = applySTGen (genWord64R r) @@ -355,8 +370,8 @@ instance RandomGen g => MonadRandom (STGen g) s (ST s) where -- | Applies a pure operation to the wrapped pseudo-random number generator. -- -- @since 1.2 -applySTGen :: (g -> (a, g)) -> STGen g s -> ST s a -applySTGen f (STGenI ref) = do +applySTGen :: (g -> (a, g)) -> STGenM g s -> ST s a +applySTGen f (STGenM ref) = do g <- readSTRef ref case f g of (!a, !g') -> a <$ writeSTRef ref g' @@ -366,7 +381,7 @@ applySTGen f (STGenI ref) = do -- pseudo-random number generator. -- -- @since 1.2 -runSTGen :: RandomGen g => g -> (forall s . STGen g s -> ST s a) -> (a, g) +runSTGen :: RandomGen g => g -> (forall s . STGenM g s -> ST s a) -> (a, g) runSTGen g action = unSTGen <$> runST (runGenM (STGen g) action) -- | Runs a monadic generating action in the `ST` monad using a pure @@ -374,7 +389,7 @@ runSTGen g action = unSTGen <$> runST (runGenM (STGen g) action) -- value. -- -- @since 1.2 -runSTGen_ :: RandomGen g => g -> (forall s . STGen g s -> ST s a) -> a +runSTGen_ :: RandomGen g => g -> (forall s . STGenM g s -> ST s a) -> a runSTGen_ g action = fst $ runSTGen g action @@ -420,9 +435,9 @@ runSTGen_ g action = fst $ runSTGen g action -- from the @mwc-random@ package: -- -- > instance (s ~ PrimState m, PrimMonad m) => MonadRandom MWC.Gen s m where --- > newtype Frozen MWC.Gen = Frozen { unFrozen :: MWC.Seed } --- > thawGen = fmap MWC.restore unFrozen --- > freezeGen = fmap Frozen . MWC.save +-- > type Frozen MWC.Gen = MWC.Seed +-- > thawGen = MWC.restore +-- > freezeGen = MWC.save -- > uniformWord8 = MWC.uniform -- > uniformWord16 = MWC.uniform -- > uniformWord32 = MWC.uniform @@ -456,9 +471,9 @@ runSTGen_ g action = fst $ runSTGen g action -- -- >>> :{ -- instance (s ~ PrimState m, PrimMonad m) => MonadRandom MWC.Gen s m where --- newtype Frozen MWC.Gen = Frozen { unFrozen :: MWC.Seed } --- thawGen = fmap MWC.restore unFrozen --- freezeGen = fmap Frozen . MWC.save +-- type Frozen MWC.Gen = MWC.Seed +-- thawGen = MWC.restore +-- freezeGen = MWC.save -- uniformWord8 = MWC.uniform -- uniformWord16 = MWC.uniform -- uniformWord32 = MWC.uniform diff --git a/stack-old.yaml b/stack-old.yaml index 750067a74..87c4784a5 100644 --- a/stack-old.yaml +++ b/stack-old.yaml @@ -51,10 +51,8 @@ extra-deps: # implement 'Prim'. So far, this is only the case on lehin's fork, so we use # that. - splitmix-0.0.4@sha256:fb9bb8b54a2e76c8a021fe5c4c3798047e1f60e168379a1f80693047fe00ad0e,4813 - # Not contained in all snapshots we want to test against - doctest-0.16.2@sha256:2f96e9bbe9aee11b47453c82c24b3dc76cdbb8a2a7c984dfd60b4906d08adf68,6942 - cabal-doctest-1.0.8@sha256:34dff6369d417df2699af4e15f06bc181d495eca9c51efde173deae2053c197c,1491 -- primitive-0.6.4.0@sha256:5b6a2c3cc70a35aabd4565fcb9bb1dd78fe2814a36e62428a9a1aae8c32441a1,2079 # Override default flag values for local packages and extra-deps flags: diff --git a/test/Spec/Range.hs b/test/Spec/Range.hs index a48ac2b4a..d9e8c0a95 100644 --- a/test/Spec/Range.hs +++ b/test/Spec/Range.hs @@ -25,10 +25,10 @@ singleton g x = result == x uniformRangeWithin :: (RandomGen g, UniformRange a, Ord a) => g -> (a, a) -> Bool uniformRangeWithin gen (l, r) = - runGenState_ gen $ \g -> + runStateGen_ gen $ \g -> (\result -> min l r <= result && result <= max l r) <$> uniformRM (l, r) g uniformRangeWithinExcluded :: (RandomGen g, UniformRange a, Ord a) => g -> (a, a) -> Bool uniformRangeWithinExcluded gen (l, r) = - runGenState_ gen $ \g -> + runStateGen_ gen $ \g -> (\result -> min l r <= result && (l == r || result < max l r)) <$> uniformRM (l, r) g diff --git a/test/Spec/Run.hs b/test/Spec/Run.hs index b0e6565d5..c0e00edb8 100644 --- a/test/Spec/Run.hs +++ b/test/Spec/Run.hs @@ -5,7 +5,7 @@ import System.Random.Monad runsEqual :: RandomGen g => g -> IO Bool runsEqual g = do - let pureResult = runGenState_ g uniformM :: Word64 + let pureResult = runStateGen_ g uniformM :: Word64 stResult = runSTGen_ g uniformM ioResult <- runGenM_ (IOGen g) uniformM atomicResult <- runGenM_ (AtomicGen g) uniformM