re-opening a closed stdin?
Mon, 25 Nov 2002 17:00:07 -0000
> Simon Marlow wrote:
> > > Simon Marlow:
> > > > [Lazy I/O] is nice, but it introduces too many problems. What
> > > > happens to any I/O errors encountered by the lazy I/O? =20
> They have to
> > > > be discarded, which means you can't effectively use lazy I/O for
> > > > robust applications anyway.
> > >
> > > Surely they are thrown as exceptions which can then be manipulated
> > > in pure code using
> > >
> > > mapExceptions :: (Exception -> Exception) -> (a -> a)
> > >
> > > and caught in the IO monad using catch?
> > No, the report clearly states that they are discarded.
> Could you please point out where? I couldn't find it with a=20
> quick look.
Section 11.2.1 in the Library Report, last paragraph.
> > We could perhaps have our own versions of the lazy I/O=20
> operations which
> > throw exceptions, but this in itself is problematic because=20
> these kind
> > of exceptions would be asynchronous in nature. If lazy I/O=20
> is allowed
> > to raise exceptions, then we have a situation where=20
> evaluating anything
> > can raise an I/O exception. In theory this shouldn't be a=20
> problem - we
> > all ought to be writing asynchronous-excpetion-safe code anyway to
> > protect against StackOverflow, but an I/O exception is=20
> often one that
> > you want to handle gracefully and recover from. I feel distinctly
> > uncomfortable about I/O exceptions being thrown by pure=20
> code, and even
> > more uncomfortable about asynchronous I/O exceptions.
> Is even the following example from the library report (section 11.8.2)
> import System
> import Char( toUpper )
> main =3D do
> [f1,f2] <- getArgs
> s <- readFile f1
> writeFile f2 (map toUpper s)
It depends what you want to happen in the event of a I/O error in the
file being read. If you want to reliably clean up, say remove f2 and
emit a helpful message, then as Haskell 98 stands you can't do it.
If we were to make the lazy I/O raise an exception in the event of an
error, then you can do the cleanup, but you have to know which
computations can force the lazy I/O and wrap appropriate exception
handlers around them. Knowing which computations can force the I/O is
There *is* a reasonable semantics for readFile: read the whole file
immediately. You don't have to generate the Haskell String eagerly,
just read the whole file into a cache and report any I/O errors. This
doesn't work too well for large files, or for using readFile/getContents
to write stream processors though.