Non-monolithic version of 'sequence' for IO monad?
Tue, 6 Nov 2001 13:52:19 +0100 (MET)
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'.