Readline read_history and write_history addition
simonmarhaskell at gmail.com
Mon Feb 4 06:53:34 EST 2008
Yitzchak Gale wrote:
> 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
Here's my (slightly provocative) take on this: a MonadIO instance is not a
complete wrapper around the IO monad, because it doesn't provide catch. It
is not the responsibility of a library that provides IO functions to
account for defficient wrappers of IO with no way to catch exceptions. The
problem is in the IO wrapper, not the library that throws exceptions.
However, I do agree that exceptions should generally be used for
exceptional conditions, rather than for general control-flow. This is an
example of a *good* reason to avoid an exception: because to use an
exception for a non-exceptional condition is poor style. Avoiding
exceptions because MonadIO has trouble with them is not a good enough
reason, IMO. We should fix MonadIO instead.
More information about the Libraries