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