[Haskell-cafe] [ANN] Safe Lazy IO in Haskell
nicolas.pouillard at gmail.com
Sun Mar 22 18:28:35 EDT 2009
Excerpts from Henning Thielemann's message of Sun Mar 22 22:52:48 +0100 2009:
> On Sun, 22 Mar 2009, nicolas.pouillard wrote:
> > Excerpts from Henning Thielemann's message of Sat Mar 21 22:27:08 +0100 2009:
> >> Maybe you know of my packages lazy-io and explicit-exception which also
> >> aim at lazy I/O and asynchronous exception handling.
> > I was indeed aware of these two packages but I think they hold orthogonal
> > ideas.
> > About the lazy-io package, as explained in the documentation one has to
> > carefully choose which operations can be lifted. In safe-lazy-io I try
> > to choose a set of well behaving combinators to replace 'getContents' in the
> > IO monad.
> > Moreover if I take the three problems of standard lazy IO in turn:
> > 1/ Control of resources: One advantage over standard lazy IO is that
> > the file opening can also be done lazily, avoiding an immediate
> > resource exhaustion. However one still relies on evaluation and garbage
> > collection to take care of closing handles, which is not satisfying since
> > handles are scarce resources.
> > 2/ Control of exceptions: If one writes a 'getContents' function such that
> > it no longer hides I/O errors during reading, how do you guarantee
> > that exceptions will happen during the LazyIO.run and not after?
> Currently I cannot guarantee anything. However my idea is to stay away
> from built-in exceptions in IO. In explicit-exception there is an
> experimental hidden module which provides an IO monad wrapper called SIO
> which cannot throw any IO exception.
> Actually, I think it's the wrong way round to build an exception-free
> monad on top of one with exceptions. Instead IO should be built on top of
> SIO, but that's not possible for historical reasons.
> The only safe operation to get into SIO is
> ioToExceptionalSIO :: IO a -> ExceptionalT IOException SIO a
> That is, it makes exceptions explicit and SIO operations can never throw
> IO exceptions. You should convert synchronous explicit exceptions of
> atomic operations like getChar into asynchronous explicit exceptions,
> combine them lazily to big operations like getContents. Then you get
> getContents :: SIO (Asynchronous.Exception IOException String)
> If you run lazy SIO operations you can't become surprised by exceptions.
It sounds like a nice idea, it would be great to have a straight-io package
to play a bit more with explicit exceptions in things like 'IO'.
For safe-lazy-io I wanted to keep the exception management as light as
possible. In particular when writing programs where most of the 'IO' errors
are considered fatals---EOF is not fatal of course but using getContents one
do not see it.
> > 3/ Determinism: when freely combining multiple inputs one risks the problem
> > mentioned by Oleg , when using your package it will depend on
> > the 'getContents' function we use:
> > a) if we 'liftIO' the standard 'getContents' function, we can have the issue.
> > b) if we write a new 'getContents' as below , then (if I got right
> > your lazy IO monad) all reads are chained. And then one has
> > to process inputs in the same order.
> I wouldn't build hClose into getContents, because you never know, whether
> the file is read until it's end. If you call a LazyIO.getContents twice,
> the contents are read sequential. In order to read file contents
> simultaneously you must call (LazyIO.run LazyIO.getContents) twice in the
> IO monad.
Right but one of the purposes of safe-lazy-io is to provides a good
management of file handles in particular closing them. Actually the
implementation of lazy inputs focus particularly on that---through the
More information about the Haskell-Cafe