
I think I've answered part of my question. There is a function that lives in the IO monad, newStdGen. This gives you a new generator with random initial state. That's the first part of the story. Then, I'm not sure, but perhaps you can call newStdGen many times during a program and get good pseudorandom behavior. For example: shuffle :: RandomGen g, Random a => g -> [a] -> [a] shuffle = ... main = do g1 <- newStdGen print (shuffle g1 [1,2,3,4,5] :: [Int]) g2 <- newStdGen print (shuffle g2 [6,7,8,9,0] :: [Int]) Does calling newStdGen twice in a row give good behavior? Is it a bad idea? Is it system-dependent? Also note that I added the Random class constraint to 'shuffle'. I haven't tested this but it might be necessary. Or not? Thanks, Mike Michael P Mossey wrote:
Duncan Coutts wrote:
So you end up with pure functions like:
shuffle :: RandomGen g => g -> [x] -> [x]
Thanks for the help, Duncan. I'm confused on one point. Don't you always need the new state of the generator back? So wouldn't this need to be:
shuffle :: RandomGen g => g -> [x] -> (g,[x])
Another approach is to hide the 'g' inside a monad. That's what MonadRandom is all about. eg:
shuffle :: [x] -> Rand [x]
One tutorial mentions the class Gen in the Test.QuickCheck module. Is "Rand" a different class defined somewhere else?
The tutorials above explain about the other random functions, for getting values of different types (not just Int) and restricted ranges of number etc.
Of course at some point you want to seed the random number generator with some initial genuinely random value (not like the 12345 we used above). That is the only place in your random-handling code that needs to do IO. All the rest of it can be pure.
What function gives you that initial random seed? (Grabs it from the system clock?)
Thanks, Mike _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe