@@ -59,6 +59,8 @@ module System.Random.Internal
5959 , uniformFloatPositive01M
6060 , uniformEnumM
6161 , uniformEnumRM
62+ , uniformListM
63+ , shuffleListM
6264
6365 -- * Generators for sequences of pseudo-random bytes
6466 , genShortByteStringIO
@@ -67,7 +69,7 @@ module System.Random.Internal
6769
6870import Control.Arrow
6971import Control.DeepSeq (NFData )
70- import Control.Monad (when )
72+ import Control.Monad (when , replicateM )
7173import Control.Monad.Cont (ContT , runContT )
7274import Control.Monad.IO.Class (MonadIO (.. ))
7375import Control.Monad.ST
@@ -78,6 +80,7 @@ import Data.Bits
7880import Data.ByteString.Short.Internal (ShortByteString (SBS ), fromShort )
7981import Data.IORef (IORef , newIORef )
8082import Data.Int
83+ import Data.List (sortOn )
8184import Data.Word
8285import Foreign.C.Types
8386import Foreign.Storable (Storable )
@@ -541,6 +544,41 @@ runStateGenST_ g action = runST $ runStateGenT_ g action
541544{-# INLINE runStateGenST_ #-}
542545
543546
547+ -- | Generates a list of pseudo-random values.
548+ --
549+ -- ====__Examples__
550+ --
551+ -- >>> import System.Random.Stateful
552+ -- >>> let pureGen = mkStdGen 137
553+ -- >>> g <- newIOGenM pureGen
554+ -- >>> uniformListM 10 g :: IO [Bool]
555+ -- [True,True,True,True,False,True,True,False,False,False]
556+ --
557+ -- @since 1.2.0
558+ uniformListM :: (StatefulGen g m , Uniform a ) => Int -> g -> m [a ]
559+ uniformListM n gen = replicateM n (uniformM gen)
560+ {-# INLINE uniformListM #-}
561+
562+ -- | Shuffle elements of a list in a random order.
563+ --
564+ -- ====__Examples__
565+ --
566+ -- >>> import System.Random.Stateful
567+ -- >>> let pureGen = mkStdGen 2023
568+ -- >>> g <- newIOGenM pureGen
569+ -- >>> shuffleListM ['a'..'z'] g :: IO String
570+ -- "renlhfqmgptwksdiyavbxojzcu"
571+ --
572+ -- @since 1.2.2
573+ shuffleListM :: StatefulGen g m => [a ] -> g -> m [a ]
574+ shuffleListM xs gen = do
575+ is <- uniformListM n gen
576+ pure $ map snd $ sortOn fst $ zip (is :: [Int ]) xs
577+ where
578+ ! n = length xs
579+ {-# INLINE shuffleListM #-}
580+
581+
544582-- | The standard pseudo-random number generator.
545583newtype StdGen = StdGen { unStdGen :: SM. SMGen }
546584 deriving (Show , RandomGen , NFData )
0 commit comments