@@ -30,6 +30,7 @@ module System.Random.Stateful
3030 -- $interfaces
3131 , StatefulGen (.. )
3232 , FrozenGen (.. )
33+ , ThawedGen (.. )
3334 , withMutableGen
3435 , withMutableGen_
3536 , randomM
@@ -257,7 +258,7 @@ instance RandomGen r => RandomGenM (TGenM r) r STM where
257258-- ([-74,37,-50,-2,3],IOGen {unIOGen = StdGen {unStdGen = SMGen 4273268533320920145 15251669095119325999}})
258259--
259260-- @since 1.2.0
260- withMutableGen :: FrozenGen f m => f -> (MutableGen f m -> m a ) -> m (a , f )
261+ withMutableGen :: ThawedGen f m => f -> (MutableGen f m -> m a ) -> m (a , f )
261262withMutableGen fg action = do
262263 g <- thawGen fg
263264 res <- action g
@@ -274,7 +275,7 @@ withMutableGen fg action = do
274275-- 4
275276--
276277-- @since 1.2.0
277- withMutableGen_ :: FrozenGen f m => f -> (MutableGen f m -> m a ) -> m a
278+ withMutableGen_ :: ThawedGen f m => f -> (MutableGen f m -> m a ) -> m a
278279withMutableGen_ fg action = thawGen fg >>= action
279280
280281
@@ -311,6 +312,7 @@ uniformListM n gen = replicateM n (uniformM gen)
311312-- @since 1.2.0
312313randomM :: forall a g m . (Random a , RandomGen g , FrozenGen g m ) => MutableGen g m -> m a
313314randomM = flip modifyGen random
315+ {-# INLINE randomM #-}
314316
315317-- | Generates a pseudo-random value using monadic interface and `Random` instance.
316318--
@@ -331,6 +333,7 @@ randomM = flip modifyGen random
331333-- @since 1.2.0
332334randomRM :: forall a g m . (Random a , RandomGen g , FrozenGen g m ) => (a , a ) -> MutableGen g m -> m a
333335randomRM r = flip modifyGen (randomR r)
336+ {-# INLINE randomRM #-}
334337
335338-- | Wraps an 'IORef' that holds a pure pseudo-random number generator. All
336339-- operations are performed atomically.
@@ -386,13 +389,15 @@ instance (RandomGen g, MonadIO m) => StatefulGen (AtomicGenM g) m where
386389instance (RandomGen g , MonadIO m ) => FrozenGen (AtomicGen g ) m where
387390 type MutableGen (AtomicGen g ) m = AtomicGenM g
388391 freezeGen = fmap AtomicGen . liftIO . readIORef . unAtomicGenM
389- thawGen (AtomicGen g) = newAtomicGenM g
390392 modifyGen (AtomicGenM ioRef) f =
391393 liftIO $ atomicModifyIORef' ioRef $ \ g ->
392394 case f (AtomicGen g) of
393395 (a, AtomicGen g') -> (g', a)
394396 {-# INLINE modifyGen #-}
395397
398+ instance (RandomGen g , MonadIO m ) => ThawedGen (AtomicGen g ) m where
399+ thawGen (AtomicGen g) = newAtomicGenM g
400+
396401-- | Atomically applies a pure operation to the wrapped pseudo-random number
397402-- generator.
398403--
@@ -466,7 +471,6 @@ instance (RandomGen g, MonadIO m) => StatefulGen (IOGenM g) m where
466471instance (RandomGen g , MonadIO m ) => FrozenGen (IOGen g ) m where
467472 type MutableGen (IOGen g ) m = IOGenM g
468473 freezeGen = fmap IOGen . liftIO . readIORef . unIOGenM
469- thawGen (IOGen g) = newIOGenM g
470474 modifyGen (IOGenM ref) f = liftIO $ do
471475 g <- readIORef ref
472476 let (a, IOGen g') = f (IOGen g)
@@ -476,6 +480,9 @@ instance (RandomGen g, MonadIO m) => FrozenGen (IOGen g) m where
476480 overwriteGen (IOGenM ref) = liftIO . writeIORef ref . unIOGen
477481 {-# INLINE overwriteGen #-}
478482
483+ instance (RandomGen g , MonadIO m ) => ThawedGen (IOGen g ) m where
484+ thawGen (IOGen g) = newIOGenM g
485+
479486-- | Applies a pure operation to the wrapped pseudo-random number generator.
480487--
481488-- ====__Examples__
@@ -533,7 +540,6 @@ instance RandomGen g => StatefulGen (STGenM g s) (ST s) where
533540instance RandomGen g => FrozenGen (STGen g ) (ST s ) where
534541 type MutableGen (STGen g ) (ST s ) = STGenM g s
535542 freezeGen = fmap STGen . readSTRef . unSTGenM
536- thawGen (STGen g) = newSTGenM g
537543 modifyGen (STGenM ref) f = do
538544 g <- readSTRef ref
539545 let (a, STGen g') = f (STGen g)
@@ -543,6 +549,9 @@ instance RandomGen g => FrozenGen (STGen g) (ST s) where
543549 overwriteGen (STGenM ref) = writeSTRef ref . unSTGen
544550 {-# INLINE overwriteGen #-}
545551
552+ instance RandomGen g => ThawedGen (STGen g ) (ST s ) where
553+ thawGen (STGen g) = newSTGenM g
554+
546555
547556-- | Applies a pure operation to the wrapped pseudo-random number generator.
548557--
@@ -636,7 +645,6 @@ instance RandomGen g => StatefulGen (TGenM g) STM where
636645instance RandomGen g => FrozenGen (TGen g ) STM where
637646 type MutableGen (TGen g ) STM = TGenM g
638647 freezeGen = fmap TGen . readTVar . unTGenM
639- thawGen (TGen g) = newTGenM g
640648 modifyGen (TGenM ref) f = do
641649 g <- readTVar ref
642650 let (a, TGen g') = f (TGen g)
@@ -646,6 +654,9 @@ instance RandomGen g => FrozenGen (TGen g) STM where
646654 overwriteGen (TGenM ref) = writeTVar ref . unTGen
647655 {-# INLINE overwriteGen #-}
648656
657+ instance RandomGen g => ThawedGen (TGen g ) STM where
658+ thawGen (TGen g) = newTGenM g
659+
649660
650661-- | Applies a pure operation to the wrapped pseudo-random number generator.
651662--
@@ -797,19 +808,17 @@ applyTGen f (TGenM tvar) = do
797808--
798809-- === @FrozenGen@
799810--
800- -- `FrozenGen` gives us ability to use any stateful pseudo-random number generator in its
801- -- immutable form, if one exists that is. This concept is commonly known as a seed, which
802- -- allows us to save and restore the actual mutable state of a pseudo-random number
803- -- generator. The biggest benefit that can be drawn from a polymorphic access to a
804- -- stateful pseudo-random number generator in a frozen form is the ability to serialize,
805- -- deserialize and possibly even use the stateful generator in a pure setting without
806- -- knowing the actual type of a generator ahead of time. For example we can write a
807- -- function that accepts a frozen state of some pseudo-random number generator and
808- -- produces a short list with random even integers.
811+ -- `FrozenGen` gives us ability to use most of stateful pseudo-random number generator in
812+ -- its immutable form, if one exists that is. The biggest benefit that can be drawn from
813+ -- a polymorphic access to a stateful pseudo-random number generator in a frozen form is
814+ -- the ability to serialize, deserialize and possibly even use the stateful generator in a
815+ -- pure setting without knowing the actual type of a generator ahead of time. For example
816+ -- we can write a function that accepts a frozen state of some pseudo-random number
817+ -- generator and produces a short list with random even integers.
809818--
810819-- >>> import Data.Int (Int8)
811820-- >>> :{
812- -- myCustomRandomList :: FrozenGen f m => f -> m [Int8]
821+ -- myCustomRandomList :: ThawedGen f m => f -> m [Int8]
813822-- myCustomRandomList f =
814823-- withMutableGen_ f $ \gen -> do
815824-- len <- uniformRM (5, 10) gen
0 commit comments