2

I am trying to understand functors and do understand the concept but not the purpose of it?

Consider following example:

val list1 = List(1,2,3)
val list2 = Functor[List].map(list1)(_ * 2)

What is the benefit over:

list1.map(x => x * 2)

?

4 Answers 4

7

The purpose is not necessarily Functor[List].map(list1)(_ * 2) but rather:

def timesTwo[F[_]: Functor](f: F[Int]) = 
  Functor[F].map(f)(_ * 2)

The ability to abstract over everything that can be mapped.

0
4

A functor is a type constructor F[_] together with a function

def fmap[A,B](f: A => B): F[A] => F[B]

(this is written differently than, e.g., in cats, but it achieves the same and is interchangeable)

So what does this mean? A type constructor is basically a mapping between types You give it a type A, and it gives you a result type F[A].

The fact that you have the function fmap means the following: You can go from F[A] to F[B] every time you were able to go from A to B.

Laws

Every functor has to obey these identites

  1. fmap(identity[A]) == identity[F[A]]
  2. fmap(a compose b) == fmap(a) compose fmap (b)

The functor laws ensure that both the type-level function (the type constructor) and the value level functions (A => B and F[A] => F[B]) work together well.

What is the benefit

The benefit is not that you can write some function with a different syntax. Indeed in your example Functor[List].map(list1)(_ * 2) is more awkward to write than simply list1.map(_ * 2).

The benefit is that you can write functions that work for any functor.

Here is an example

import cats.Functor

def foo[A,B,F[_]: Functor](fb: F[B], ab: A => B)(eab: Either[F[A],F[B]]): F[B] = 
    eab.fold(fa => Functor[F].map(fa)(ab),identity)
1

A functor is a type class that abstracts all types of similar map operations that can be made. In doing so, we can operate these types of instances in a uniform way.

0

I think it's useful to look at the type signature of functor's map function

map :: (a -> b) -> Functor a -> Functor b

This gives us a way to put a value in a container (Functor) and operate on that value using an ordinary function (with map), all without having to take the value out of the container.

A Functor can then be considered like a higher-order type; ie, it's a value that contains another value, but has a uniform interface for interacting with it – this interface gives functors a unique form of expression that makes them particularly suitable for certain problems

Not the answer you're looking for? Browse other questions tagged or ask your own question.