
My thread about randomness got hijacked so I need to restate my remaining question here. Is it acceptable to write pure routines that use but do not return generators, and then call several of them from an IO monad with a generator obtained by several calls to newStdGen? shuffle :: RandomGen g => g -> [a] -> [a] shuffle = ... foo :: [a] -> [a] -> IO () foo xs ys = do g1 <- newStdGen print $ shuffle g1 xs g2 <- newStdGen print $ shuffle g2 ys Does this kind of thing exhibit good pseudorandomness? Thanks, Mike

On Wed, Oct 7, 2009 at 2:59 PM, Michael Mossey
My thread about randomness got hijacked so I need to restate my remaining question here. Is it acceptable to write pure routines that use but do not return generators, and then call several of them from an IO monad with a generator obtained by several calls to newStdGen?
It's gross. What if you don't want IO as part of this computation? If you have a random generator that supports splitting (something rather hard to do from what I understand), I prefer not to return the new generator but instead to split it. So, using your shuffle:
shuffle :: RandomGen g => g -> [a] -> [a] shuffle = ...
foo :: RandomGen g => [a] -> [a] -> g -> ([a],[a]) foo xs ys gen = let (gen1, gen2) = split gen in (shuffle gen1 xs, shuffle gen2 ys) Luke

Luke Palmer wrote:
On Wed, Oct 7, 2009 at 2:59 PM, Michael Mossey
wrote: My thread about randomness got hijacked so I need to restate my remaining question here. Is it acceptable to write pure routines that use but do not return generators, and then call several of them from an IO monad with a generator obtained by several calls to newStdGen?
It's gross. What if you don't want IO as part of this computation?
I don't quite follow your response. I want a program that initializes the generator from the global generator because I want different behavior every time I run it. So it will need IO. That's what I was trying to demonstrate. And I was wondering if one can get around the difficulty of passing the generator from call to call by using newStdGen in this way. Mike

Am Mittwoch 07 Oktober 2009 23:28:59 schrieb Michael Mossey:
Luke Palmer wrote:
On Wed, Oct 7, 2009 at 2:59 PM, Michael Mossey
wrote: My thread about randomness got hijacked so I need to restate my remaining question here. Is it acceptable to write pure routines that use but do not return generators, and then call several of them from an IO monad with a generator obtained by several calls to newStdGen?
It's gross. What if you don't want IO as part of this computation?
I don't quite follow your response. I want a program that initializes the generator from the global generator because I want different behavior every time I run it. So it will need IO. That's what I was trying to demonstrate. And I was wondering if one can get around the difficulty of passing the generator from call to call by using newStdGen in this way.
Mike
Documentation says: newStdGen :: IO StdGen Applies split to the current global random generator, updates it with one of the results, and returns the other. So it's as safe as split is.

On Wed, Oct 7, 2009 at 2:28 PM, Michael Mossey
I don't quite follow your response. I want a program that initializes the generator from the global generator because I want different behavior every time I run it. So it will need IO. That's what I was trying to demonstrate. And I was wondering if one can get around the difficulty of passing the generator from call to call by using newStdGen in this way.
You should only have to call newStdGen once: main = do g <- newStdGen let (g1,g2) = split g let xs = [1..10] print $ shuffle g1 xs print $ shuffle g2 xs

On Wed, Oct 7, 2009 at 1:59 PM, Michael Mossey
My thread about randomness got hijacked so I need to restate my remaining question here. Is it acceptable to write pure routines that use but do not return generators, and then call several of them from an IO monad with a generator obtained by several calls to newStdGen?
shuffle :: RandomGen g => g -> [a] -> [a] shuffle = ...
foo :: [a] -> [a] -> IO () foo xs ys = do g1 <- newStdGen print $ shuffle g1 xs g2 <- newStdGen print $ shuffle g2 ys
Does this kind of thing exhibit good pseudorandomness?
If you believe in the safety of the split operation (which I don't), then yes, since use of it is what's happening behind the scenes. In other words, provided you're a faithful sort and split doesn't make you squirm too much, you don't need to plug all that ugly IO in there.

Excerpts from Bryan O'Sullivan's message of Wed Oct 07 23:25:10 +0200 2009:
On Wed, Oct 7, 2009 at 1:59 PM, Michael Mossey
wrote: My thread about randomness got hijacked so I need to restate my remaining question here. Is it acceptable to write pure routines that use but do not return generators, and then call several of them from an IO monad with a generator obtained by several calls to newStdGen?
shuffle :: RandomGen g => g -> [a] -> [a] shuffle = ...
foo :: [a] -> [a] -> IO () foo xs ys = do g1 <- newStdGen print $ shuffle g1 xs g2 <- newStdGen print $ shuffle g2 ys
Does this kind of thing exhibit good pseudorandomness?
If you believe in the safety of the split operation (which I don't), then ^^^^^^^^^^^^^^^^ | Can you elaborate on that? ---------------------------------+
Best regards, -- Nicolas Pouillard http://nicolaspouillard.fr
participants (6)
-
Bryan O'Sullivan
-
Daniel Fischer
-
Luke Palmer
-
Michael Mossey
-
Nicolas Pouillard
-
Ryan Ingram