On Tue, 23 Jul 2002, Nick Name wrote:
It's relatively simple.
The random number generator is a pure function, so it cannot be nondeterministic. So, you have a way to build this function with a seed, since the author wanted you to be able to do so, I could say for completeness, or reuse sake.
But what you want is nondeterminism. How can you get that? With I/O of course. So, apart from the fact I am not going to search the "getTime" function, but it's probable haskell has one, and apart from the fact that getTime is also nondeterministic, here's a program that prints a true random number. Since this program uses I/O, it's a monadic action.
You shouldn't _need_ to be in the IO monad to get random numbers (although if you choose to that can be a good choice). Clearly there's the need to initialise the generator, but if you want `random' random numbers (as opposed to a known sequence of random numbers for debugging) getting the value of time via an unsafePerformIO is as good as anything else. From then on, the pseudo-random number generator will deterministically produce what are hopefully `acceptably random looking' numbers. As I made some (frankly rather confused) contribution to the debate that led to the current formulation of Random.hs, I'll have a go at explaining the intended usage. Supposing you wanted a program that generated a list of random names from a preset list, then you could have f :: [Int] -> [Name] -> [Name] f xs names = map (\x->names!!x) xs where you supply a (lazily generated) infinite list of random integers in xs. This is good because by changing the initialisation of the function generating the lazy list, you can get reliably __the same random list__ for debugging purposes. The problem comes if you've got, e.g., a need to generate two random lists: a good solution is clearly something along the lines of g::[Int]->[Name]->[Name]->([Name],[Name]) g xs names1 names2 = (f ys names1,f zs names2) where (ys,zs) = `two statistically independent random list generated from xs' The problem is to find a convenient way to split up the original list for passing to sub functions where not only are the pieces independent as complete lists, but also that no matter what pattern of further splitting the subfunctions use all pairs below are statistically independent. The idea used in the Randoms library is to have an abstract data-type StdGen which you can apply `randoms' to to get an infinite list of random numbers and which you can (deterministically) `split' into two new StdGen's which should give statistically independent sequences. With these you should get (i) the ability to write programs by passing around either generators or infinite lists, so that you can set them to produce the same results each time for debugging purposes. (ii) no need for the IO monad to infect functions purely because the need random numbers. I don't know the answer to the original posters question; however Randoms.hs contains primitive getRandomSeed :: IO Integer which I believe you can use either to get the seed within the IO monad directly or via unsafePerformIO if you don't want the IO monad around. HTH, ___cheers,_dave_________________________________________________________ www.cs.bris.ac.uk/~tweed/ | `It's no good going home to practise email:tweed@cs.bris.ac.uk | a Special Outdoor Song which Has To Be work tel:(0117) 954-5250 | Sung In The Snow' -- Winnie the Pooh