The type looks like this.
As we said, it’s very close to
fmap which you have implemented before. We’ll call the function argument
f, but you might have called it something else.
Here’s another flavor – semantically the same, syntactically different.
You could, of course, write a little property test to make sure that it’s behaving the same as
liftA2 @Maybe from
base, but that’s probably not necessary.
Given the similarities with
Functor, see if you can write an
Either. You can implement either
liftA2or both. You may want to un-import
Eitherand its constructors from
Prelude. You’ll need to have a
Functorinstance in scope for
Remember you have a choice of implementing the tie-fighter or
liftA2 for your instance, but you must have
pure either way. We’ve used the
Either names for our instances here (un-importing them from
The types of the
liftA2 as specialized to
Either a are as follows:
Left values, which contain the
w, are treated the same as
Nothing in the
You should be noticing a pattern at this point, not just with these but a commonality with the structure of
Functor instances, too. There is usually only one sensible implementation for a given type For
Functor there is only ever one sensible implementation, or so we’re told – we’ve never proven this ourselves. Therefore, there is a language extension you can use to derive
Functor instances, much as you derive
Show and others. For now, we’d encourage you to keep writing instances by hand as long as you can stand it. The day you find yourself thinking how trivial it is to write this next
Functor instance, it’s probably safe to start deriving them., and you just do the simplest thing. Part of the reason we have you write so many instances – and you should be writing even more! – is because doing these until they are mechanical because you’ve internalized the pattern is the best way we know to make these patterns really useful to you.