Lutz Donnerhacke lutz at iks-jena.de
Tue Nov 27 08:51:26 EST 2007

```* manolo at austrohungaro.com wrote:
> I'm trying to program an implementation of the St. Petersburg game in
> Haskell. There is a coin toss implied, and the random-number generation is
> driving me quite mad. So far, I've tried this:
>
> import Random

import System.Random  -- time goes on, interfaces change

> increment :: Int -> Int
> increment b = b + 1
>
>
> main =  do	let b = 0
> 		let c = randomRIO (1,2)
> 		until (c == 1)	increment b
>               	return b

In Haskell you take it the other side around:
- Given a random number generator
System.Random.newStdGen :: IO StdGen

- you generate an infinite list of coin flip results
System.Random.randoms  :: (RandomGen g) =>          g -> [a]
System.Random.randomRs :: (RandomGen g) => (a,a) -> g -> [a]

- you are interested in the the first elements of a given value
takeWhile :: (a -> Bool) -> [a] -> [a]

- and need to compute the length of this list
length :: [a] -> Int

To model the result of a coin flip, you need two possible values.
Your choice [1,2] is possible, but the boolean values are much easier.
Let's choose True for number up and False otherwise.

Put it together:

main :: IO ()
main = do
rnd <- newStdGen
let result = computeResult rnd
print result

computeResult :: (RandomGen g) => g -> Int
computeResult = length . takeWhile not . randoms

Or in short:

main = print . length . takeWhile not . randoms =<< newStdGen
```