Readline read_history and write_history addition

Yitzchak Gale gale at
Sat Feb 2 16:14:28 EST 2008

Alexander Dunlap wrote:
>>> For instances where an exception would be too intrusive, I don't see
>>> how it would be too hard to write a wrapper function

I wrote:
>>  In a library that does not have direct access to the IO
>>  monad, it would be not just hard - it would be impossible.
>>  That is because of type restrictions in the current versions
>>  of catch, block, and friends.

Judah Jacobson wrote:
> You haven't said why something like the following would not be sufficient:
> readHistoryM :: MonadIO m => String -> m Bool
> readHistoryM file = liftIO $ do
>     result <- try (readHistory file)
>     return (result == Right ())

Because a library - other than readline itself - can't
force its users to do that.

OK. Here's a simplified real-world example. Say you want to
write a simple library that interfaces the text-to-speech facilities
available on multiple platforms. To play nicely with programs
written in a monadic style, the interface might be something like:

class MonadIO m => Speech m where
  sayText :: String -> m ()
  runSpeech :: m a -> IO a

instance Speech SomeSpeechSystem where
  sayText t = ...
  runSpeech x = do
    liftIO startSomeSpeechSystem
    ret <- x
    liftIO stopSomeSpeechSystem
    return ret

Unfortunately, bracket is not available. So if x throws an
uncaught IO exception, you may leave around zombies,
database corruption, missiles armed for launch, etc.

Well, if your speech system doesn't arm any missiles,
you may consider it a reasonable risk to use this
library in programs that could throw an IO exception
on some rare error condition.

But the proposal here is to raise the exception in a
common situation that will definitely occur in regular
usage. That may be fine in Java or Python, but it
is a bad idea for IO exceptions in Haskell.

Alexander Dunlap wrote:
> So why couldn't you have a Utils.hs file that imports System.IO and
> provides the wrapper around readHistory? Then you can use the
> tryReadHistory function in your MonadIO-exporting module _exactly_ the
> same way as the original readHistory function.

You can. But if you are writing a library, your users
might not.


More information about the Libraries mailing list