This is very much a newbie question, and although I can find partial answers, I'm still having difficulty getting the whole thing to work. I have a collection of functions in a module with work with a particular data type I've designed. And sometimes I need to create a list of random values. We might consider my types as polynomials, given as lists of their coefficients. So I should just need to call a randomPoly
function (say) to generate new lists each time it's called. For simplicity all lists can be the same length (say 4) and with the same sized elements - say between 0 and 9.
So what I want is to be able to do something like this (in ghci):
>>> setRandomSeed 42
>>> randomPoly
[6,5,0,4]
>>> randomPoly
[9,6,3,5]
>>> randomPoly
[7,3,9,2]
I can of course obtain different random lists by simply passing a new seed to the generator each time I need a new list:
>>> randomPoly st = map (`mod` 10) $ take 4 $ randoms (mkStdGen st) :: [Integer]
But I don't want to do this: I want to set an initial seed once, and let State take care of managing the current value of the generator from then on.
At this stage I'm not much interested in the nitty-gritty of monads, State, and all the rest - I'm looking for as close to an "off the shelf" solution as possible. I just want something I can use. Most examples seem to be very keen to teach all about how the State monad works - and this is a very honorable notion - but right now all I want is some quick and simple method of creating random lists when I want them.
For example here's a silly function which creates random lists until a sum of all values is even:
mkEvenPoly :: Int -> [Integer]
mkEvenPoly st
| even $ sum p = p
| otherwise = mkEvenPoly $ s+1
where
p = map (`mod` 10) $ take 4 $ randoms (mkStdGen st) :: [Integer]
Note that each time I need to pass a new generating value to mkStdGen
. Can I do this sort of thing with the State monad - storing the current value of the generator (which is returned by mkStdGen
) and then using it for the next random call?