The discussion of random numbers in Haskell should perhaps
move elsewhere as it is quite restricted, but it shows one
problem with the functional approach to *practical* programming:
in *my opinion* our fascination by the Monadic Approach to 
Universe and Everything, and the possibility to program in an 
imperative way has a negative side effect. My friends physicists
asked me once after being told that imperative constructs are
possible in Haskell: "so, what's the point in using this language?
Fortran code is simpler than "do" in Haskell..."

==

Lennart advocates the use of streams :

>   let mis = take n (random ss1)
>       is  = take n (toInt (random ss2))
>       ds  = take n (toDouble (random ss3))
>   in  ...

and I agree entirely with him, although the coding details might
be different. Streams are nice and safe. And methodologically
sane.


Ralf Hinze :

> My problem with your solution is that you must supply a seed for every
> call (perhaps you don't know how many do you require) and that you may
> end up with pseudo-random numbers which are not random at all. Because
> you choose the seeds badly. That's why I thread the (current) seed
> through all those value generators. Of course, instead of threadening
> a seed one could thread an infinite list of Ints.


Actually I remind you that *practically all classical* generators are
based on integer congruences, and if the parametrization (A,C,M) of
gen = \X -> (A*X + C) `mod` M
is chosen correctly, the quality of the generator is ensured
independently
of the seed. The problem with the Lennart example is that you might get 
two, three, etc. generators which are clones, eventually shifted by some
number of items.

But the main idea is very simple.
The only thing to do rnd = (iterate gen seed) and do whatever you wish
with it, for example map (/ M) on order to have numbers in (0 .. 1), 
pick them by dozens in order to get Gaussians, etc. I would change the
Lennart example by using splitAt instead of take, and continuing the
next
instance with the remaining part of the master sequence.

But, if I really wished to have different random streams, I would change
the parameteres in generating this master sequence, and this is all.
Such
Good Numbers could be provided in the library. Sometimes other schemes
are
used, for example one generator pumps the pseudo-randoms into a (short)
array, and a second one picks up one of them, which kills the short and
medium range correlations, even if the basic parametrization is not
perfect... This would need monadic arrays or other similar contraptions.

There is another issue which should be raised one day: there is no 
reason to discuss random numbers if we won't use them seriously. Well,
in order to apply functional methods to simulations, Monte-Carlo 
integrations, optimizations, etc. we need to put a good deal of code
into the functional framework.

Best regards

Jerzy Karczmarczuk
Caen, France.


Reply via email to