Applicative Identity

Dan Doel dan.doel at gmail.com
Fri Jul 6 22:19:14 EDT 2007


Hello,

I ran into a tiny snag recently, attempting to write a library for a monad + 
transformer. If one uses MTL, it typically nice to be able to do something 
like the following:

    newtype FooT m a = FooT { runFooT :: ... }

    ... instances for FooT

    newtype Foo a = Foo { unFoo :: FooT Identity a }
        deriving (Functor, Monad, ...)

Since the normal monad is just the case of the transformer parameterized by 
the Identity monad. However, we now have the Control.Applicative library, 
which sits in between Functors and Monads, so it seems reasonable to provide 
instances of those, as well. However, Identity (and, for that matter, all of 
the monads in MTL, I think) lacks an appropriate instance for Applicative, so 
generalized deriving can't be used there.

On the other side, Control.Applicative has a newtype WrappedMonad, which 
provides such instances for an arbitrary monad. However, it has the reverse 
problem: There are no Monad (and related) instances for WrappedMonad. So, it 
seems that the full gamut of instances can't be automatically derived in this 
way, as the libraries currently stand.

Now, this clearly isn't a dire situation, but it might be nice to fill in one 
or both of these gaps so the libraries play a little nicer with each other. 
For instance, I think the Identity instance is as simple as:

    instance Applicative Identity where
        pure = Identity
        f <*> a = Identity $ runIdentity f (runIdentity a)

And, of course, in general, one can fill in the MTL instances as easily as:

    instance Applicative MTLType where
        pure  = return
        (<*>) = ap

Although it may be less trivial with transformers (though I assume Applicative 
a => Applicative (T a) aren't too hard).

Many thanks,
Dan Doel


More information about the Libraries mailing list