Reputation: 911
This is a function to generate a list of given number of random numbers within a range, but I'm confused on how to call on this function. I think a seed is needed for StdGen, but really appreciate if someone can tell how exactly to call this function.
randomList :: (Random a) => (a,a) -> Int -> StdGen -> [a]
randomList bnds n = take n . randomRs bnds
Upvotes: 0
Views: 834
Reputation: 40797
You supply a range (in the form of a tuple), a number of elements, and an StdGen
, i.e. randomList (0,10) 100 gen
, where gen :: StdGen
. An StdGen
just represents the standard random number generator, and there are multiple ways to get one:
getStdGen
, which is an IO action returning the global StdGen
.mkStdGen
, passing in a seed (as an Int
). Of course, mkStdGen seed
will produce the same random numbers for the same seed
; this is useful if you want deterministic results but, of course, won't help if you want different random numbers each time :)For example, getStdGen >>= randomList (0,10) 100
has type (Random a) => IO [a]
, and produces a list of 100 random numbers from 0 to 10 when executed (for example, by doing numbers <- getStdGen >>= randomList (0,10) 100
in a do
block).
However, randomList
doesn't return the final StdGen
obtained after the numbers are generated, and so, unless you create a new StdGen
for each use of it, it'll always return the same results. The action I showed above will produce different results each time the program is run, but if it's used multiple times with the same range over the course of a single run of your program, it'll produce the same numbers each time.
This can be fixed by manually generating the list instead of using randomRs
; for example:
randomList :: (Random a) => (a,a) -> Int -> StdGen -> ([a], StdGen)
randomList _ 0 gen = ([], gen)
randomList bnds n gen = (x:xs, gen'')
where
(x, gen') = randomR bnds gen
(xs, gen'') = randomList bnds (n-1) gen'
This can then be used with the global StdGen
using getStdRandom
; for example:
main :: IO ()
main = replicateM_ 10 $ do
xs <- getStdRandom $ randomList (0,10) 100
print xs
This should produce 10 distinct lists of 100 elements each.
Upvotes: 3
Reputation: 54081
Sample:
main :: IO ()
main = do g <- getStdGen
print (randomList (1, 100) 5 g :: [Integer])
will output e.g.
[42,42,15,7]
The g
is the random number generator, in this case the "global random number generator".
Here's the documentation
Upvotes: 4