
Hello, 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 input. 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 = ... with 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.
Cheers Robert