Malcolm Wallace wrote: | > sequence :: (Monad m) => [m a] -> m [a] | > sequence = foldr (liftM2 (:)) (return []) | Are you *really* sure that the latter consumes its | entire input before producing any result? It looks | pretty lazy to me, and I seem to be able to give it an | infinite list of computations and yet start receiving | results immediately.... This is not true, as the following example demonstrates: main :: IO () main = sequence [ return i | i <- [1..] ] >>= print The IO monad is strict. This means that one cannot look at the result `a' of a computation of type `IO a' before all the IO in that computation is done. (Note that in other monads that are not strict, the above computation works without problems.) The function `unsafeInterleaveIO' in Hugs, GHC and HBC (and NHC?) can turn a computation of type `IO a' into an "empty" computation of type `IO a', which means we can start looking at the result before any IO is done. This operator is often used inside implementations to implement functions like `hGetContents' and `readFile'. /Koen.