Re: Takusen and strictness, and perils of getContents
simonmarhaskell at gmail.com
Wed Mar 7 05:43:40 EST 2007
oleg at pobox.com wrote:
> Simon Marlow wrote:
>> Anyway, I just wanted to point out that nowadays we have the option of
>> using imprecise exceptions to report errors in lazy I/O.
> Is this really a solution? Currently, getContents reports no errors
> but does perfect error recovery: the result of the computation prior to
> the error is preserved and reported to the caller. Imprecise
> exceptions give us error reporting -- but no error recovery. All
> previously computed results are lost. Here's a typical scenario:
> do l <- getContents
> return (map process l)
> If an error occurs reading lazy input, we'd like to log the error and
> assume the input is terminated with EOF. If getContents raises an
> imprecise exception, what do we do?
> return (map process (catch l (\e -> syslog e >> return )))
> That of course won't work: l is a value rather than an effectful
> computation; besides; catch can't occur in the pure code to start
> with. What we'd like are _resumable_ exceptions. The exception handler
> receives not only the exception indicator but also the continuation
> where the exception has occurred. Invoking this continuation means
> error recovery. Resumable exceptions are used extensively in CL; they
> are also available in OCaml. So, hypothetically we could write
> do l <- getContents
> resume_catch (return (map process l))
> (\e k -> syslog e >> k )
> Besides the obvious typing problem, this won't work for the reason
> that exceptions raised in the pure code are _imprecise_ -- that is, no
> precise continuation is available, even in principle.
Yes, I think I agree with that. Resumable exceptions don't make any sense for
pure code (I can certainly imagine implementing them though, and they make sense
in the IO monad).
But all is not lost: if an exception is raised during getContents for example,
you still have the partial results: the list ends in an exception, and I can
write a function that returns the non-exceptional portion (in IO, of course).
More information about the Haskell-Cafe