Skip to content

Commit 4aab7e3

Browse files
committed
Add overwriteGen to FrozenGen
1 parent 320b2a0 commit 4aab7e3

File tree

4 files changed

+34
-2
lines changed

4 files changed

+34
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 1.3.0
22

3-
* Add `modifyGen` to the `FrozenGen` type class
3+
* Add `modifyGen` and `overwriteGen` to the `FrozenGen` type class
44
* Add `splitGen` and `splitMutableGen`
55
* Switch `randomM` and `randomRM` to use `FrozenGen` instead of `RandomGenM`
66
* Deprecate `RandomGenM` in favor of a more powerful `FrozenGen`

src/System/Random/Internal.hs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,17 @@ class StatefulGen (MutableGen f m) m => FrozenGen f m where
309309
-- @since 1.2.0
310310
thawGen :: f -> m (MutableGen f m)
311311

312-
-- | Apply a pure function to the frozen generator.
312+
-- | Apply a pure function to the frozen pseudo-random number generator.
313313
--
314314
-- @since 1.3.0
315315
modifyGen :: MutableGen f m -> (f -> (a, f)) -> m a
316316

317+
-- | Overwrite contents of the mutable pseudo-random number generator with the
318+
-- supplied frozen one
319+
--
320+
-- @since 1.3.0
321+
overwriteGen :: MutableGen f m -> f -> m ()
322+
overwriteGen mg fg = modifyGen mg (const ((), fg))
317323

318324
-- | Splits a pseudo-random number generator into two. Overwrites the mutable
319325
-- wrapper with one of the resulting generators and returns the other.
@@ -478,6 +484,8 @@ instance (RandomGen g, MonadState g m) => FrozenGen (StateGen g) m where
478484
thawGen (StateGen g) = StateGenM <$ put g
479485
modifyGen _ f = state (coerce f)
480486
{-# INLINE modifyGen #-}
487+
overwriteGen _ f = put (coerce f)
488+
{-# INLINE overwriteGen #-}
481489

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

src/System/Random/Stateful.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@ instance (RandomGen g, MonadIO m) => FrozenGen (IOGen g) m where
473473
g' `seq` writeIORef ref g'
474474
pure a
475475
{-# INLINE modifyGen #-}
476+
overwriteGen (IOGenM ref) = liftIO . writeIORef ref . unIOGen
477+
{-# INLINE overwriteGen #-}
476478

477479
-- | Applies a pure operation to the wrapped pseudo-random number generator.
478480
--
@@ -538,6 +540,8 @@ instance RandomGen g => FrozenGen (STGen g) (ST s) where
538540
g' `seq` writeSTRef ref g'
539541
pure a
540542
{-# INLINE modifyGen #-}
543+
overwriteGen (STGenM ref) = writeSTRef ref . unSTGen
544+
{-# INLINE overwriteGen #-}
541545

542546

543547
-- | Applies a pure operation to the wrapped pseudo-random number generator.
@@ -639,6 +643,8 @@ instance RandomGen g => FrozenGen (TGen g) STM where
639643
g' `seq` writeTVar ref g'
640644
pure a
641645
{-# INLINE modifyGen #-}
646+
overwriteGen (TGenM ref) = writeTVar ref . unTGen
647+
{-# INLINE overwriteGen #-}
642648

643649

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

test/Spec/Stateful.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,22 @@ withMutableGenSpec toIO frozen =
6464
r' <- withMutableGen_ frozen action
6565
pure $ x == y && r == r'
6666

67+
overwriteMutableGenSpec ::
68+
forall f m. (FrozenGen f m, Eq f, Show f)
69+
=> (forall a. m a -> IO a)
70+
-> f
71+
-> Property IO
72+
overwriteMutableGenSpec toIO frozen =
73+
forAll $ \n -> monadic $ toIO $ do
74+
let action = uniformListM (abs n + 1) -- Non-empty
75+
((r1, r2), frozen') :: ((String, String), f) <- withMutableGen frozen $ \mutable -> do
76+
r1 <- action mutable
77+
overwriteGen mutable frozen
78+
r2 <- action mutable
79+
modifyGen mutable (const ((), frozen))
80+
pure (r1, r2)
81+
pure $ r1 == r2 && frozen == frozen'
82+
6783
splitMutableGenSpec ::
6884
forall f m. (RandomGen f, FrozenGen f m, Eq f, Show f)
6985
=> (forall a. m a -> IO a)
@@ -86,6 +102,8 @@ statefulSpecFor toIO toStdGen =
86102
(showsTypeRep (typeRep (Proxy :: Proxy f)) "")
87103
[ testProperty "withMutableGen" $
88104
forAll $ \(f :: f) -> withMutableGenSpec toIO f
105+
, testProperty "overwriteGen" $
106+
forAll $ \(f :: f) -> overwriteMutableGenSpec toIO f
89107
, testProperty "splitGen" $
90108
forAll $ \(f :: f) -> splitMutableGenSpec toIO f
91109
, testGroup

0 commit comments

Comments
 (0)