
On Sat, Mar 1, 2008 at 8:18 AM, Milos Hasan
Here's a minimal summing example that illustrates the difference. The following works fine, since the elements are generated lazily and summed on the fly, as expected:
randFloats :: [Float] randFloats = randoms (mkStdGen 0)
main = do let xs = take 1000000 randFloats print $ sum xs
But this overflows, because the list is created before being summed, and the take function goes into awfully deep recursion:
randFloats :: [Float] randFloats = randoms (mkStdGen 0)
main = do xs <- return $ take 1000000 randFloats print $ sum xs
It is definitely the strictness analyzer biting you here. In ghci, the behavior of these two programs is identical (stack overflow). As kalman said, if you replate sum with foldl' (+) 0 in each of these programs, the behavior is still identical (correct). As a side note, one of the monad laws is this: return x >>= f = f x So your two programs are semantically equivalent (there's nothing about IO that forces the evaluation of the list). If you're building some sort of tree out of these values, you're going to want to make sure that whatever fold you do (be it using foldl' or recursion) is strict, so that you don't get a huge thunk that doesn't have any information. Luke