
Bryan Burgers wrote:
I did not look at it long enough to tell you why there is an infinite loop. However, think about it on a high level with me.
You want a stream of these random numbers (I'm not sure what a triangular distribution is, but that's okay). To get one of these, you take two random numbers and perform a combination function (\x y -> (x + y) `div` 2 ) on them.
Yes, precisely. Triangular distribution is a probability distribution that is equivalent to two rolls of dice. This means that the numbers at the middle of the range are much more likely to pop up than numbers at the edge of the range. It is quite close to gaussian distribution. I'm toying around with a signal processing toolkit in Haskell. The noise I'm trying to generate here is needed for a process called dithering, in which some noise is added to a quantized signal in order to improve it's accuracy. But not just any kind of noise will do for this purpose. The best noise for dithering is noise with triangular or gaussian probability distribution, instead of white noise which has equal probability distribution. But, like you said, that's not really important for the purposes of this discussion. What is is that we take a bunch of random numbers, perform some mathematical operation on them in order to introduce some statistical properties to the series and return the processed series. There are several different probability distribution functions, triangular being one of them. Triangular distribution requires two random numbers to generate one, and some functions require more than that.
So you can lift this from one random numbers to a stream of random numbers if you have have two streams of random numbers instead of just two random numbers. zipWith is the function that brings us from one number to a stream of numbers.
tpdfs range = do g <- newStdGen -- get a random generator (g1, g2) <- return $ split g -- make two random generators out of it return $ zipWith combine (randomRs range g1) (randomRs range g2) -- get two streams of random numbers, and combine them elementwise.
combine x y = (x + y) `div` 2
So, moving on to the next question, how well do you think this solution would scale if we would need n random numbers to generate one? Niko