>>> let roll = uniformR (1, 6) :: RandomGen g => g -> (Word, g) >>> let rolls = unfoldr (Just . roll) :: RandomGen g => g -> [Word] >>> let pureGen = mkStdGen 42 >>> take 10 (rolls pureGen) :: [Word] [1,1,3,2,4,5,3,4,6,2]See System.Random for more details.
>>> let rollM = uniformRM (1, 6) :: StatefulGen g m => g -> m Word >>> let pureGen = mkStdGen 42 >>> runStateGen_ pureGen (replicateM 10 . rollM) :: [Word] [1,1,3,2,4,5,3,4,6,2]The monadic adapter System.Random.Stateful.runStateGen_ is used here to lift the pure pseudo-random number generator pureGen into the System.Random.Stateful.StatefulGen context. The monadic interface can also be used with existing monadic pseudo-random number generators. In this example, we use the one provided in the mwc-random package:
>>> import System.Random.MWC as MWC >>> let rollM = uniformRM (1, 6) :: StatefulGen g m => g -> m Word >>> monadicGen <- MWC.create >>> replicateM 10 (rollM monadicGen) :: IO [Word] [2,3,6,6,4,4,3,1,5,4]See System.Random.Stateful for more details.
>>> import Data.Int >>> randomIO :: IO Int32 114794456This function is equivalent to getStdRandom random and is included in this interface for historical reasons and backwards compatibility. It is recommended to use uniformM instead, possibly with the globalStdGen if relying on the global state is acceptable.
>>> import System.Random.Stateful >>> uniformM globalStdGen :: IO Int32 -1768545016
>>> let gen = mkStdGen 26 >>> fst $ randomR ('a', 'z') gen 'z' >>> fst $ randomR ('a', 'z') gen 'z'For continuous types there is no requirement that the values lo and hi are ever produced, but they may be, depending on the implementation and the interval. There is no requirement to follow the Ord instance and the concept of range can be defined on per type basis. For example product types will treat their values independently:
>>> fst $ randomR (('a', 5.0), ('z', 10.0)) $ mkStdGen 26 ('z',5.22694980853051)In case when a lawful range is desired uniformR should be used instead.
>>> let gen = mkStdGen 26 >>> fst $ randomR ('a', 'z') gen 'z' >>> fst $ randomR ('a', 'z') gen 'z'For continuous types there is no requirement that the values lo and hi are ever produced, but they may be, depending on the implementation and the interval. There is no requirement to follow the Ord instance and the concept of range can be defined on per type basis. For example product types will treat their values independently:
>>> fst $ randomR (('a', 5.0), ('z', 10.0)) $ mkStdGen 26 ('z',5.22694980853051)In case when a lawful range is desired uniformR should be used instead.
>>> randomRIO (2020, 2100) :: IO Int 2028Similar to randomIO, this function is equivalent to getStdRandom randomR and is included in this interface for historical reasons and backwards compatibility. It is recommended to use uniformRM instead, possibly with the globalStdGen if relying on the global state is acceptable.
>>> import System.Random.Stateful >>> uniformRM (2020, 2100) globalStdGen :: IO Int 2044
>>> import System.Random.Stateful >>> let pureGen = mkStdGen 139 >>> g <- newIOGenM pureGen >>> randomM g :: IO Double 0.33775117339631733You can use type applications to disambiguate the type of the generated numbers:
>>> :seti -XTypeApplications >>> randomM @Double g 0.9156875994165681
>>> import System.Random.Stateful >>> let pureGen = mkStdGen 137 >>> g <- newIOGenM pureGen >>> randomRM (1, 100) g :: IO Int 52You can use type applications to disambiguate the type of the generated numbers:
>>> :seti -XTypeApplications >>> randomRM @Int (1, 100) g 2
>>> rollDice = getStdRandom (randomR (1, 6)) >>> replicateM 10 (rollDice :: IO Int) [1,1,1,4,5,6,1,2,2,5]This is an outdated function and it is recommended to switch to its equivalent applyAtomicGen instead, possibly with the globalStdGen if relying on the global state is acceptable.
>>> import System.Random.Stateful >>> rollDice = applyAtomicGen (uniformR (1, 6)) globalStdGen >>> replicateM 10 (rollDice :: IO Int) [2,1,1,5,4,3,6,6,3,2]