Let's cover another interesting and yet simple topic in this article, Functors. Informally, we can call anything with a map function as a Functor. Yes! You got it right if it crossed in your mind that Monads are functors too. Still, no idea what a Monad is... go check out my last article.
Definition
For a more formal discussion, we will define the map function:
def map[A, B](fa: F[A])(f: A => B): F[B]
The definition expects a type object F[A] of type A and a transformer (A => B) and returns a type object of type B - F[B].
Functor Laws
As we had discussed for Monads, not everything with a map function can be called as Functor. It needs to obey the Functor Laws:
1) Identity: When you map to itself then it gives back itself.
f_t.map(t => t) == f_t
List as an example for the law:
scala> val list = List(1, 2, 3, 5, 67, 23, 4)
list: List[Int] = List(1, 2, 3, 5, 67, 23, 4)
scala> list.map(x => x)
res0: List[Int] = List(1, 2, 3, 5, 67, 23, 4)
1) Composition: When you map it a composite functions f and g, is the same as mapping it to f and then to g.
f_t.map(g(f(_))) == f_t.map(f).map(g)
List as an example for the law:
scala> val f : Int => Int = x => x*2
f: Int => Int
scala> val g : Int => String = x => x.toString
g: Int => String
scala> list.map(x => g(f(x)))
res6: List[String] = List(2, 4, 6, 10, 134, 46, 8)
scala> list.map(f).map(g)
res7: List[String] = List(2, 4, 6, 10, 134, 46, 8)
Testing a Functor!
Let's test a known Functor like Option in scala with what we have learnt right now:
{i} def map[A, B](fa: F[A])(f: A => B): F[B]
{ii} f_t.map(t => t) == f_t
{iii} f_t.map(g(f(_))) == f_t.map(f).map(g)
Corresponding verification for Option in scala, for {i}
scala> Option(123).map(x => x.toString)
res0: Option[String] = Some(123)
for {ii}
scala> Option(123).map(x => x)
res1: Option[Int] = Some(123)
for {iii}
scala> Option(123).map(x => g(f(x)))
res3: Option[String] = Some(246)
scala> Option(123).map(f).map(g)
res4: Option[String] = Some(246)
I leave you with the exercise of verifying popular functors with the above rules.
Note: You will not find exclusive use of functors because of their limited capabilities, but special cases of functors like Monads are used widely!
Comments