
On 7/16/07, Niko Korhonen
I'm writing some code to generate a dither (=noise) signal. I'm trying to generate an infinite series of noise with triangular distribution but my code hangs into an infinite loop. The problem is that I'm not very good with Haskell IO yet and I can't figure out how to write this piece of IO code without it looping infinitely.
So, in short, how do I do this without getting into an infinite loop:
tpdfs :: (Int, Int) -> IO [Int] tpdfs (low, high) = do first <- getStdRandom (randomR (low, high)) second <- getStdRandom (randomR (low, high)) let r = (first + second) `div` 2 rest <- tpdfs (low, high) return (r : rest)
Caller site:
do nums <- tpdfs (2, 12) let ns = take 7 nums
Niko
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. 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 Uh, I know that's a very poor explanation, but hopefully it gives you an alternate way to look at the problem.