From a1276fec996979baf4e0a9d45d9b60262ed5aed1 Mon Sep 17 00:00:00 2001 From: Leonhard Markert Date: Fri, 8 May 2020 15:40:18 +0200 Subject: [PATCH] StdGen: constructor accessible via Internal only (#123) Fixes https://github.com/haskell/random/issues/59 by making 'StdGen' not an instance of 'Read'. --- System/Random.hs | 2 +- System/Random/Internal.hs | 10 ++++++---- System/Random/Monad.hs | 2 +- bench/Main.hs | 8 ++++---- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/System/Random.hs b/System/Random.hs index bff4145f7..120dd37da 100644 --- a/System/Random.hs +++ b/System/Random.hs @@ -293,7 +293,7 @@ getStdGen :: MonadIO m => m StdGen getStdGen = liftIO $ readIORef theStdGen theStdGen :: IORef StdGen -theStdGen = unsafePerformIO $ SM.initSMGen >>= newIORef +theStdGen = unsafePerformIO $ SM.initSMGen >>= newIORef . StdGen {-# NOINLINE theStdGen #-} -- |Applies 'split' to the current global pseudo-random generator, diff --git a/System/Random/Internal.hs b/System/Random/Internal.hs index 5ba916b8f..7ec513ad8 100644 --- a/System/Random/Internal.hs +++ b/System/Random/Internal.hs @@ -5,6 +5,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RankNTypes #-} @@ -32,7 +33,7 @@ module System.Random.Internal , MonadRandom(..) -- ** Standard pseudo-random number generator - , StdGen + , StdGen(..) , mkStdGen -- * Monadic adapters for pure pseudo-random number generators @@ -404,9 +405,10 @@ runStateGenST g action = runST $ runStateGenT g action -- | The standard pseudo-random number generator. -type StdGen = SM.SMGen +newtype StdGen = StdGen { unStdGen :: SM.SMGen } + deriving (RandomGen, Show) -instance RandomGen StdGen where +instance RandomGen SM.SMGen where next = SM.nextInt genWord32 = SM.nextWord32 genWord64 = SM.nextWord64 @@ -420,7 +422,7 @@ instance RandomGen SM32.SMGen where -- | Constructs a 'StdGen' deterministically. mkStdGen :: Int -> StdGen -mkStdGen s = SM.mkSMGen $ fromIntegral s +mkStdGen = StdGen . SM.mkSMGen . fromIntegral -- | The class of types for which a uniformly distributed value can be drawn -- from all possible values of the type. diff --git a/System/Random/Monad.hs b/System/Random/Monad.hs index dc0110886..585023775 100644 --- a/System/Random/Monad.hs +++ b/System/Random/Monad.hs @@ -211,7 +211,7 @@ instance RandomGen r => RandomGenM STGenM r s (ST s) where -- -- >>> import Data.Int (Int8) -- >>> runGenM (IOGen (mkStdGen 217)) (`uniformListM` 5) :: IO ([Int8], IOGen StdGen) --- ([-74,37,-50,-2,3],IOGen {unIOGen = SMGen 4273268533320920145 15251669095119325999}) +-- ([-74,37,-50,-2,3],IOGen {unIOGen = StdGen {unStdGen = SMGen 4273268533320920145 15251669095119325999}}) -- -- @since 1.2 runGenM :: MonadRandom g s m => Frozen g -> (g s -> m a) -> m (a, Frozen g) diff --git a/bench/Main.hs b/bench/Main.hs index 0f1b8eaf4..0b6a6a537 100644 --- a/bench/Main.hs +++ b/bench/Main.hs @@ -22,10 +22,10 @@ main = do let !sz = 100000 defaultMain [ bgroup "baseline" - [ let !stdGen = mkStdGen 1337 in bench "nextWord32" $ nf (genMany SM.nextWord32 stdGen) sz - , let !stdGen = mkStdGen 1337 in bench "nextWord64" $ nf (genMany SM.nextWord64 stdGen) sz - , let !stdGen = mkStdGen 1337 in bench "nextInt" $ nf (genMany SM.nextInt stdGen) sz - , let !stdGen = mkStdGen 1337 in bench "split" $ nf (genMany SM.splitSMGen stdGen) sz + [ let !smGen = SM.mkSMGen 1337 in bench "nextWord32" $ nf (genMany SM.nextWord32 smGen) sz + , let !smGen = SM.mkSMGen 1337 in bench "nextWord64" $ nf (genMany SM.nextWord64 smGen) sz + , let !smGen = SM.mkSMGen 1337 in bench "nextInt" $ nf (genMany SM.nextInt smGen) sz + , let !smGen = SM.mkSMGen 1337 in bench "split" $ nf (genMany SM.splitSMGen smGen) sz ] , bgroup "pure" [ bgroup "random"