"callbacks" in Haskell

Robert Vollmert rvollmert@gmx.net
Wed, 25 Jun 2003 13:33:07 +0200


I've been having a little trouble writing a module that waits for and
handles IO events, e.g. by reading from a pipe. It seemed natural to
use some form of callbacks here, though that may very well be the
wrong approach. I'd be happy to hear of alternatives.

Anyway, I got a callback-based approach to work to some extent, but
am not happy with the callback's type.

The abstract form of this module is as follows. I'd appreciate any

A class that specifies what we expect of the base monad.
> class (Monad m) => MonadReq m

A class that specifies what we provide to the callback.
> class (Monad m) => MonadProv m

The module's main function.
> f :: (MonadReq m) => Callback m a -> m a
> f c = ...

Internally, we wrap the base monad with some monad transformer, say
> data InternalT m a = ...
> instance MonadTrans InternalT
so that the callback can access the base monad, and
> instance (MonadReq m) => MonadProv (InternalT m)
so that we can actually provide MonadProv.

A type for callback that works is
> type Callback m a = InternalT m a
What I don't like about this is that we shouldn't really need to
expose what exact monad transformer we use. Also, if we added a second
function that also runs the callback in a MonadProv but that uses a
different transformer (for instance, needing to keep track of some
extra state), we'd need a new callback type.

What seems to be the right type is
> type Callback m a = forall t. (MonadTrans t, MonadProv (t m)) => t m a
which sort of works with '-fglasgow-exts' (what's this extension
called?). However, it seems to cause all kinds of problems, e.g. pairs
of this type appear to be illegal.