In the world of functional programming you will quickly come across the concept of a Functor. What I present below is a simple example that might provide some intuition, with references for further reading.

### What’s the Problem?

We often want to use a function that takes an instance of A and returns an instance of B in a context where we have an instance of *M[A]* and need an instance of *M[B]*. The most common example is the *map* method on List, Option, etc.

So the problem is:

Given a function f that takes an A and returns a B, how can we construct a new function that takes an M[A] and returns an M[B]

for any M?

### Functors

A Functor accepts a function, A ⇒ B, and returns a new function M[A] ⇒ M[B], where M is any *kind*.

So without further ado, here’s the code:

object Functorise extends App { // This is a Functor trait Functor[M[_]] { /* convert f into a function mapping M[A] to M[B] * eg. if M were List, and f was Int ⇒ String * fmap would yield List[Int] ⇒ List[String] */ def fmap[A, B](f: A ⇒ B): M[A] ⇒ M[B] } /* Here are a couple of examples for Option and List Functors * They are implicit so they can be used below in enrichWithFunctor */ implicit object OptionFunctor extends Functor[Option] { def fmap[A, B](f: A ⇒ B): Option[A] ⇒ Option[B] = option ⇒ option map f } implicit object ListFunctor extends Functor[List] { def fmap[A, B](f: A ⇒ B): List[A] ⇒ List[B] = list ⇒ list map f } /* enrichWithFunctor is an implicit to enrich any kind * with an fmap method. * List, Option and any other Foo[X] can be enriched with the * new method. */ implicit def enrichWithFunctor[M[_], A](m: M[A]) = new { /* fmap requires an implicit functor, whose type is M, to which it * delegates to do the real work */ def mapWith[B](f: A ⇒ B)(implicit functor: Functor[M]): M[B] = functor.fmap(f)(m) } // some examples println(List(1, 2) mapWith (_ + 1)) // List(2, 3) println(some(1) mapWith (_ + 1) mapWith (_ * 3)) // Some(6) println(none[Int] mapWith (_ + 1)) // None def some[A](a: A): Option[A] = Some(a) def none[A]: Option[A] = None } |

### What is Going On?

Lets take the *List(1, 2) mapWith (_ + 1)* example and go through it.

There is no *mapWith* method on List, so an implicit method is searched for that can turn the List into something that does have a *mapWith* method. Thus, *enrichWithFunctor* is found and called with the *List(1, 2)* which returns an anonymous class with the *mapWith* method required.

By the way, to understand more about that M[_], watch Daniel Spiewak’s High Wizardry in the Land of Scala talk.

That anonymous class also has a type parameter, M, which has now been fixed to List, and so *mapWith* in this class looks like this:

def mapWith[B](f: A ⇒ B)(implicit functor: Functor[List]): List[B] = functor.fmap(f)(m) |

The *mapWith* method requires an implicit Functor[List] to be available, and the ListFunctor object is just that. So when *functor.fmap(f)* is called, it is the ListFunctor’s *fmap* method being called.

*ListFunctor.fmap(f)* takes a function, in our example its *(i:Int) ⇒ i + 1*, and returns a new function *(list:List[Int]) ⇒ list.map(_ + 1)*.

Finally, *m*, the *List(1, 2)* we started with that was enriched with the *mapWith* method, is applied to the new function which results in a new List.

### But Why?

All we’ve done here is create a complicated looking bunch of code that just ends up calling methods on Option and List that already exist, specifically the map method.

Yes, in these examples thats true.

The real idea is that we’ve created *a general abstraction for all kinds, including those that don’t have a map method*. All a user of this code needs to do is have an implicit Functor in scope for the kind they would like to map over.

Furthermore, this is a building block for some interesting things that come next like Applicative Functors.

Finally, you don’t need to implement this yourself, Scalaz has it already for you to exploit.

#### Further Reading

- Learn You a Haskell’s Chapter on Functors, Applicative Functors and Monoids
- Heiko Seeberger’s fantastic Introduction to Category theory in Scala
- Scalaz Functor Examples