# Functor

A non-mathematical introduction to functors.

`Option`

and `List`

are two well-known classes, both of which have the function `map`

that takes a function that is applied to the values contained by the `List`

or `Option`

.

Here are two functions that take `List[Int]`

and `Option[Int]`

and increments the values:

```
def inc(o: Option[Int]): Option[Int] = o.map(i => i + 1)
def inc(l: List[Int]): List[Int] = l.map(i => i + 1)
```

The `inc`

functions do not care about `Option`

or `List`

particularly, they need a
way to work on the values they contain, but sadly `inc`

is duplicated. It doesn’t have to be.

One way to fix this is to use a `Functor`

that supplies a `map`

function for any `F[_]`

.

```
// scala 3
trait Functor[F[_]] {
extension [A, B](x: F[A])
def map(f: A => B): F[B]
}
```

Given `x: F[A]`

, `Functor[F]`

provides a `map`

method. Here is `inc`

written using `Functor[F]`

:

```
def inc[F[_]: Functor](a: F[Int]): F[Int] = a.map(i => i + 1)
```

`F[_]: Functor`

means that it requires an *instance* of `Functor[F]`

.
Scala finds that instance by looking in lots of places
for it, one being the companion object of the `F[_]`

.

For `Option`

and `List`

those instances are:

```
given Functor[Option] with {
extension [A, B](m: Option[A])
override def map(f: A => B): Option[B] = m.map(f)
}
given Functor[List] with {
extension [A, B](m: List[A])
override def map(f: A => B): List[B] = m.map(f)
}
```

Your own classes can play too:

```
final case class Blub[A](v: A)
object Blub {
given Functor[Blub] with {
extension [A, B](blub: Blub[A])
override def map(f: A => B): Blub[B]
= Blub(f(blub.v))
}
}
inc(Blub(1)) gives Blub(2)
```

Note that this is an example of the typeclass pattern, read more here.

## Laws

A proper functor must obey two laws:

*Identity*: Mapping with the*identity*function is a no-op*Composition*:`fa.map(f).map(g) = fa.map(f.andThen(g)`