
I've uploaded this change (with a much more useful error message) as D327
on Phabricator. I have done some very limited testing, and it passes GHC's
validation (on Linux), but I would really appreciate if some people who use
a lot of lazy IO could test this against their programs to make sure it
doesn't produce errors in any cases when it shouldn't.
Thanks,
David
On Mon, Jul 21, 2014 at 4:16 PM, David Feuer
Currently,
withFile "foo" hGetContents >>= putStrLn
prints out an empty line, the better to confuse newbies.
I propose modifying the lazyRead function in GHC.IO.Handle.Text that currently reads
lazyRead :: Handle -> IO String lazyRead handle = unsafeInterleaveIO $ withHandle "hGetContents" handle $ \ handle_ -> do case haType handle_ of ClosedHandle -> return (handle_, "") SemiClosedHandle -> lazyReadBuffered handle handle_ _ -> ioException (IOError (Just handle) IllegalOperation "hGetContents" "illegal handle type" Nothing Nothing)
to something like
lazyRead :: Handle -> IO String lazyRead handle = unsafeInterleaveIO $ withHandle "hGetContents" handle $ \ handle_ -> do case haType handle_ of ClosedHandle -> return (handle_, error "Forcing the result of a lazy read led to an attempt to read from a closed handle.") SemiClosedHandle -> lazyReadBuffered handle handle_ _ -> ioException (IOError (Just handle) IllegalOperation "hGetContents" "illegal handle type" Nothing Nothing)
Ideally that error should instead be something to throw an imprecise exception, but I don't know how to use those yet. I can't personally see a way for this to break sane, working code, but the folks on #ghc thought it should be discussed and debated on list.
David Feuer