[Haskell-cafe] St. Petersburg Game

Thomas Davie tom.davie at gmail.com
Tue Nov 27 08:52:08 EST 2007

> main =  do	let b = 0
> 		let c = randomRIO (1,2)
> 		until (c == 1)	increment b
>              	return b
> This is intended to print the number of consecutive heads (i.e., 2)  
> before
> the first tail, but I get the following error:
> ERROR "StPetersburg.hs":8 - Type error in application
> *** Expression     : until (c == 1) increment b
> *** Term           : c == 1
> *** Type           : Bool
> *** Does not match : Int -> Bool
> I don't really see what's going on, so any help will be more than  
> welcome.
> I hope this is a suitable question for the Haskell Café list.

I'm not familiar with the problem, so I won't comment on how I would  
implement it.  However what you appear to be doing is trying to write  
something in an imperative style.

If you want to generate random coin tosses and count how many are  
heads, I suggest you write a function that returns an infinite list of  
coin toss results.  Something like

tosses :: IO ([Int])
tosses = do ts <- tosses
             return (randomRIO (1,2):ts)

Then your main function merely needs to count them:

main = do ts <- tosses
           return $ countHeads ts

countHeads = if (head fg == 1) then 0 else length fg where fg = head $  
group ts

Your immediate error is caused by a misunderstanding of how until works.

Until essentially is a restricted while loop implemented with  
recursion.  It takes three things:
1) A condition for stopping looping
2) A thing to do in the loop
3) A value to start with.

Because there's no mutable state, a while loop can't alter the program  
state, so we must do something else instead.  What we do is we have a  
function for computing whether we're done looping or not, and we pass  
a value into it. 

More information about the Haskell-Cafe mailing list