n00b
n00b

Reputation: 911

How does one call on this Haskell function?

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

Answers (2)

ehird
ehird

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

Johannes Weiss
Johannes Weiss

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

Related Questions