[Haskell-cafe] St. Petersburg Game
Luke Palmer
lrpalmer at gmail.com
Tue Nov 27 08:56:16 EST 2007
On Nov 27, 2007 1:27 PM, <manolo at austrohungaro.com> wrote:
> Hello,
>
> 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:
Yeah, random number generation is one of those things in Haskell that
can be tricky. But it looks like you're struggling more with the idea
of monadic programming. That is expected :-)
> import Random
>
> increment :: Int -> Int
> increment b = b + 1
This is unnecessary; it can just be written (+1). (I.e. wherever you
said "increment" you could write "(+1)" instead)
> main = do let b = 0
> let c = randomRIO (1,2)
> until (c == 1) increment b
> return b
You can think of this block as four "statements", one after the other.
the "do-until" thing doesn't delimit anything, i.e. doesn't work the
way you think it does. Let me rewrite this so it's clearer what's
going on:
main = do { let b = 0;
let c = randomRIO (1,2);
until (c == 1) increment b;
return b;
}
In particular, until is a function, and you've given it three
arguments: c == 1 (which is False), increment, and b.
To solve this problem you'll probably want to use recursion, since it
is a loop. There are "higher-order" ways to loop, but they all boil
down to recursion in the end.
So let's write a function which does this, call it count:
count :: Int -> IO Int
That is the type. It takes an integer representing the current count,
does some IO and returns an integer. Specifically, it should take the
current count and flip a coin. If the coin comes up tails, it should
just return the current count. It it comes up heads, it should call
itself again with 1 + the current count as an argument. I'll get you
started
count currentCount = do
coin <- randomRIO (1,2)
...
We use <- to run an action and get its result; we use let .. = to
define the meaning of a symbol (but nothing is run). Using let just
gives a shorter name for an expression.
Why don't you try to write the rest? main will look like:
main = do
flips <- count 0
print flips
I also recommend going through a tutorial which others will doubtless
recommend to you until you get to monads (or skip ahead to monads and
see if you understand).
Luke
More information about the Haskell-Cafe
mailing list