[Haskell-cafe] [ANN] Safe Lazy IO in Haskell
nicolas.pouillard
nicolas.pouillard at gmail.com
Sun Mar 22 13:51:11 EDT 2009
Excerpts from Henning Thielemann's message of Sat Mar 21 22:27:08 +0100 2009:
>
> On Fri, 20 Mar 2009, Nicolas Pouillard wrote:
>
> > Hi folks,
> >
> > We have good news (nevertheless we hope) for all the lazy guys standing there.
> > Since their birth, lazy IOs have been a great way to modularly leverage all the
> > good things we have with *pure*, *lazy*, *Haskell* functions to the real world
> > of files.
>
> 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?
3/ Determinism: when freely combining multiple inputs one risks the problem
mentioned by Oleg [1], 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 [2], then (if I got right
your lazy IO monad) all reads are chained. And then one has
to process inputs in the same order.
However I've found the underlying idea of your monad brilliant. I've tried
a little to use something similar as a base for the implementation but didn't
succeed.
> With lazy-io, you are
> able to write more complicated things than getContents. I needed this for
> HTTP communication that is run by demand. That is when the HTTP response
> header is requested, then the function could send a HTTP request first. Is
> it possible and sensible to combine this with safe-lazy-io?
While currently focusing only on reading file handles, the long term purpose
for this technique is to have new primitives like reading on sockets, using
bytestrings...
> I have also code that demonstrates the usage of explicit asynchronous
> exceptions. I have however still not a set of combinators that makes
> working with asynchronous exceptions as simple as working with synchronous
> ones:
> http://hackage.haskell.org/cgi-bin/hackage-scripts/package/spreadsheet
I also think that explicit asynchronous exceptions could be part of the equation,
however I currently don't know how to mix them well.
Best regards,
[1]: http://www.haskell.org/pipermail/haskell/2009-March/021064.html
[2]
hGetContents :: Handle -> LIO.T String
hGetContents h = lazyRead
where lazyRead = do
isEOF <- liftIO $ hIsEOF h
if isEOF
then do
unit <- liftIO $ hClose h
return $ unit `seq` []
else do
c <- liftIO $ hGetChar h
cs <- lazyRead
return $ c : cs
--
Nicolas Pouillard
More information about the Haskell-Cafe
mailing list