[Haskell-cafe] Re: Help with IO and randomR

Niko Korhonen niko.korhonen at gmail.com
Tue Jul 17 02:38:05 EDT 2007


Tillmann Rendel wrote:
> (A) will be executed before (B) because of the IO monad. But you want r
> to be returned before rest is computed. I would split tpdfs in two
> functions: a pure function converting a infinite list of random numbers
> to another infinite list of random numbers, and an IO-function creating
> the original infinite list of random numbers:
> 
>   tpdfs' :: [Int] -> [Int]
>   tpdfs' (x:y:rest) = (x + y) `div` 2 : tpdfs' rest
> 
>   tpdfs :: (Int, Int) -> IO [Int]
>   tpdfs range = do
>     gen <- newStdGen
>     return (tpdfs' (randomRs range gen))

This seems like a good solution since it scales well with probability
functions that require more than two random numbers in order to produce
one. I could just write different versions of tpdfs' to process the
stream and feed the functions to tpdfs. Nice.

> I'm not sure your aproach is numerically correct. Let's assume range =
> (0, 1). The resulting number could be
> 
>   (0 + 0) `div` 2 = 0
>   (0 + 1) `div` 2 = 0
>   (1 + 0) `div` 2 = 0
>   (1 + 1) `div` 2 = 1
> 
> with equal probability. Is this what you want?

Come to think of it, a better formula would be something like:

round(x/2 + y/2)

round(0/2 + 0/2) = 0
round(0/2 + 1/2) = round(0.5) = 1
round(1/2 + 0/2) = round(0.5) = 1
round(1/2 + 1/2) = = 1

But that's only because of rounding issues. Otherwise this is exactly
what I want. Triangular distribution is equivalent to two rolls of dice,
meaning that numbers at the middle of the range are much more likely to
pop up than numbers at the edge of the range. Quite like in gaussian
probability distribution.

It's just that the range (0, 1) is too short for the function to work
properly with integer arithmetics. It's difficult to say what the middle
of the range (0, 1) should be. If we always round the result to the
nearest integer, the "middle of the range" is 1. The fixed formula
demostrates that the numbers at the middle of the range (round(0.5)) are
most likely to appear.

Niko



More information about the Haskell-Cafe mailing list