
[redirecting to haskell-cafe]
On 3/1/07, Dave Tapley
However this latter case gets stuck in an infinite loop, terminating on a stack overflow.
My question asks why this is the case, when laziness should ensure only the first 10 cases need to be computed.
You didn't say which function you had narrowed down the stack overflow to, but I suspect it's here:
firstTen :: IO [Int] firstTen = do infiniteNums <- iterateM addRand randNum return (take 10 infiniteNums)
In order for IO to work the way you'd expect, you have to be able to specify which IO operations happen in what order, which is exactly what a do-block within the IO monad specifies. But specifying the order of operations also means specifying in what order evaluation happens. So, the code you've written means "evaluate infiniteNums fully (in order that we might do whatever IO operations it involves before the return statement), then return the first 10 elements of its result." Since you're forcing evaluation of an infinite list, the program loops infinitely. If you find this counter-intuitive, you wouldn't be the first, but there's no other sensible interpretation for the code you've written. Deferring evaluation of infiniteNums in this case would mean that IO would happen in a strange and unpredictable order (or if it actually wouldn't, then the compiler isn't smart enough to know that.) I would solve this problem by writing a version of iterateM that takes the length of the desired list as an argument (e.g., 10 in your example), which sadly breaks modularity, but as I explained above, working within the IO monad necessitates that. Someone more l33t than me may be able to suggest a more elegant solution, though. Cheers, Kirsten -- Kirsten Chevalier* chevalier@alum.wellesley.edu *Often in error, never in doubt "They killed, they maimed, and they called information for numbers they could easily look up in the book." -- Woody Allen