
The root problem is that random number generation is inherently stateful, and so the familiar imperative idioms don't translate directly into a pure functional language. In a C-like language, each invocation of "rand()" mutates a secret piece of state lurking off-stage; pure functional code doesn't have the option of doing this. What you should probably be using is an infinite list of random numbers (see "randoms" in "Random"). With regard to your IO question, note that "return" "puts the IO back on", as it were; all this is carefully organised so you *can't* quietly file the IO's off values. The trick is to write almost everything in pure functions, then have a little bit of monad-y glue which connects all these ethereal abstractions (what might happen) to the merely contingent (what actually does). Disclaimer: I'm no haskell expert. John P.S. Sorry, but I can't resist this. With apologies to Allen Ginsberg: IO Howl ------- Monad! Monad! Nightmare of Monad! Monad the loveless! Mental Monad! Monad the heavy judger of men! Monad the incomprehensible prison! Monad the crossbone soulless jailhouse and Congress of sorrows! Monad whose buildings are judgement! Monad the vast stone of war! Monad the stunned governments! Monad whose mind is pure machinery! Monad whose blood is running money! Monad whose fingers are ten armies! Monad whose breast is a cannibal dynamo! Monad whose ear is a smoking tomb!