Skip to content

Commit

Permalink
Merge pull request idontgetoutmuch#117 from haskell/global-stdgen
Browse files Browse the repository at this point in the history
Add `globalStdGen`
  • Loading branch information
lehins authored Sep 5, 2021
2 parents d819629 + 29adb56 commit dd23693
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# 1.2.1

* Add `globalStdGen`
* Addition of `initStdGen`
* Addition of `runStateGenST_`
* Ensure that default implementation of `ShortByteString` generation uses unpinned memory.
Expand Down
5 changes: 0 additions & 5 deletions src/System/Random.hs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ import Data.IORef
import Data.Word
import Foreign.C.Types
import GHC.Exts
import System.IO.Unsafe (unsafePerformIO)
import System.Random.GFinite (Finite)
import System.Random.Internal
import qualified System.Random.SplitMix as SM
Expand Down Expand Up @@ -367,10 +366,6 @@ setStdGen = liftIO . writeIORef theStdGen
getStdGen :: MonadIO m => m StdGen
getStdGen = liftIO $ readIORef theStdGen

theStdGen :: IORef StdGen
theStdGen = unsafePerformIO $ SM.initSMGen >>= newIORef . StdGen
{-# NOINLINE theStdGen #-}

-- |Applies 'split' to the current global pseudo-random generator,
-- updates it with one of the results, and returns the other.
newStdGen :: MonadIO m => m StdGen
Expand Down
12 changes: 10 additions & 2 deletions src/System/Random/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
#if __GLASGOW_HASKELL__ >= 800
{-# LANGUAGE TypeFamilyDependencies #-}
#else
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
#endif
{-# OPTIONS_HADDOCK hide, not-home #-}

Expand All @@ -39,6 +39,7 @@ module System.Random.Internal
-- ** Standard pseudo-random number generator
, StdGen(..)
, mkStdGen
, theStdGen

-- * Monadic adapters for pure pseudo-random number generators
-- ** Pure adapter
Expand Down Expand Up @@ -76,10 +77,11 @@ import Control.Monad.Cont (ContT, runContT)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.ST
import Control.Monad.ST.Unsafe
import Control.Monad.State.Strict (StateT(..), State, MonadState(..), runState)
import Control.Monad.State.Strict (MonadState(..), State, StateT(..), runState)
import Control.Monad.Trans (lift)
import Data.Bits
import Data.ByteString.Short.Internal (ShortByteString(SBS), fromShort)
import Data.IORef (IORef, newIORef)
import Data.Int
import Data.Word
import Foreign.C.Types
Expand Down Expand Up @@ -572,6 +574,12 @@ instance RandomGen SM32.SMGen where
mkStdGen :: Int -> StdGen
mkStdGen = StdGen . SM.mkSMGen . fromIntegral

-- | Global mutable veriable with `StdGen`
theStdGen :: IORef StdGen
theStdGen = unsafePerformIO $ SM.initSMGen >>= newIORef . StdGen
{-# NOINLINE theStdGen #-}


-- | The class of types for which a uniformly distributed value can be drawn
-- from all possible values of the type.
--
Expand Down
18 changes: 17 additions & 1 deletion src/System/Random/Stateful.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module System.Random.Stateful
, randomM
, randomRM
, splitGenM
, globalStdGen

-- * Monadic adapters for pure pseudo-random number generators #monadicadapters#
-- $monadicadapters
Expand Down Expand Up @@ -335,6 +336,18 @@ newtype AtomicGen g = AtomicGen { unAtomicGen :: g}
newAtomicGenM :: MonadIO m => g -> m (AtomicGenM g)
newAtomicGenM = fmap AtomicGenM . liftIO . newIORef


-- | Global mutable standard pseudo-random number generator. This is the same
-- generator that was historically used by `randomIO` and `randomRIO` functions.
--
-- >>> replicateM 10 (uniformRM ('a', 'z') globalStdGen)
-- "tdzxhyfvgr"
--
-- @since 1.2.1
globalStdGen :: AtomicGenM StdGen
globalStdGen = AtomicGenM theStdGen


instance (RandomGen g, MonadIO m) => StatefulGen (AtomicGenM g) m where
uniformWord32R r = applyAtomicGen (genWord32R r)
{-# INLINE uniformWord32R #-}
Expand Down Expand Up @@ -368,7 +381,7 @@ instance (RandomGen g, MonadIO m) => FrozenGen (AtomicGen g) m where
-- 7879794327570578227
--
-- @since 1.2.0
applyAtomicGen :: MonadIO m => (g -> (a, g)) -> (AtomicGenM g) -> m a
applyAtomicGen :: MonadIO m => (g -> (a, g)) -> AtomicGenM g -> m a
applyAtomicGen op (AtomicGenM gVar) =
liftIO $ atomicModifyIORef' gVar $ \g ->
case op g of
Expand Down Expand Up @@ -408,6 +421,8 @@ newtype IOGen g = IOGen { unIOGen :: g }
newIOGenM :: MonadIO m => g -> m (IOGenM g)
newIOGenM = fmap IOGenM . liftIO . newIORef



instance (RandomGen g, MonadIO m) => StatefulGen (IOGenM g) m where
uniformWord32R r = applyIOGen (genWord32R r)
{-# INLINE uniformWord32R #-}
Expand Down Expand Up @@ -716,6 +731,7 @@ runSTGen_ g action = fst $ runSTGen g action
-- $setup
-- >>> import Control.Monad.Primitive
-- >>> import qualified System.Random.MWC as MWC
-- >>> writeIORef theStdGen $ mkStdGen 2021
--
-- >>> :set -XFlexibleContexts
-- >>> :set -XFlexibleInstances
Expand Down

0 comments on commit dd23693

Please sign in to comment.