Simplest way to generate an infinite list of random numbers.
import System.Random as R main = do gen <- R.getStdGen print $ take 10 $ R.randoms gen
randoms construct an infinite list:
randoms g = (\(x,g') -> x : randoms g') (random g)
2) State monad
The previous method is simple, but doesn't return a generator, so effectively, the generated numbers are the only one available. To get some random variable and a new generator, the state monad can be used.
import Control.Monad.State genRng :: RandomGen g => State g Int genRng = do gen <- get let (val, gen') = R.random gen put gen' return val main = do gen <- R.getStdGen -- get 10 random numbers and the final generator let (vals, finalGen) = runState (replicateM 10 genRng) gen print vals
This approach also lends itself to more complex operation, for example, returning a tuple:
genRngTuple = do gen <- get let (val1, gen') = R.random gen let (val2, gen'') = R.random gen' put gen'' return (val1, val2)
3) Simplifing with
genRng function is a bit verbose and can be simplified with
import Control.Monad.State genRng' :: RandomGen g => State g Int genRng' = state R.Random main = do gen <- R.getStdGen print $ evalState (replicateM 10 genRng') gen
This approach is much nicer when returning tuple for example:
genRngTuple' = do a <- state R.random b <- state R.random return (a, b)
This way, no need to do any bookkeeping with the internal state.