lazyio-0.1.0.3: Run IO actions lazily while respecting their order

Safe HaskellNone
LanguageHaskell98

System.IO.Lazy

Description

Caution:

  • Although this module calls unsafeInterleaveIO for you, it cannot take the responsibility from you. Using this module is still as unsafe as calling unsafeInterleaveIO manually. Thus we recommend to wrap the lazy I/O monad into a custom newtype with a restricted set of operations which is considered safe for interleaving I/O actions.
  • Operations like hClose are usually not safe within this monad, since they will only get executed, if their result is consumed. Since this result is often () this is quite unusual. It will also often be the case, that not the complete output is read, and thus the closing action is never reached. It is certainly best to call a closing action after you wrote the complete result of the lazy I/O monad somewhere.
  • return a :: LazyIO a is very different from interleave (return a) :: LazyIO a. The first one does not trigger previous IO actions, whereas the second one does. This is the reason why we do not instantiate MonadIO with liftIO = LazyIO.interleave, despite the matching type signatures. One of the MonadIO laws explicitly requires return a = liftIO (return a).
  • We advise to lift strict IO functions into the lazy IO monad. Lifting a function like readFile may lead to unintended interleaving. In the future we may enforce that using the deepseq package.

Use it like

import qualified System.IO.Lazy as LazyIO

LazyIO.run $ do
   LazyIO.interleave $ putStr "enter first line:"
   x <- LazyIO.interleave getLine
   LazyIO.interleave $ putStr "enter second line:"
   y <- LazyIO.interleave getLine
   return x

Because only the first entered line is needed, only the first prompt and the first getLine is executed.

Documentation

run :: T a -> IO a Source

interleave :: IO a -> T a Source