top of page
Writer's picturePranay Kundu

Functors - Functional Programming with Scala - 101 Series!

Updated: Jan 17, 2021

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.

Functor meme

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.

Monad meme Functor

Note: You will not find exclusive use of functors because of their limited capabilities, but special cases of functors like Monads are used widely!


98 views0 comments

Comments


bottom of page