Tom Tom - 2 months ago 13
Scala Question

Why does Functor is Higher-Kinded type

I have following functor definition

trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
object ListFunctor extends Functor[List] { //
def map[A, B](f: A => B)(data: List[A]): List[B] = data map f
}


In scala, it is very common that
F
is a collection type, such as List,Seq,Option, I would ask why Functor has to be higher kinded type, and what does the type parameter
F
really mean?

Answer Source

why Functor has to be higher kinded type

Functor has to be higher kinded because we want to abstract over a type parameter which itself takes a type parameter.

The types that Functor deals with are called "first order kinds" and their kind is of * -> *. When you look at the implementations you provide for a Functor, it makes sense, we're basically abstracting over the inner type parameter, for example when you define a functor for List, as you did in your example, you define it as a Functor[List]. As you see, we're not creating a functor for a specific List[Int], but rather any type parameter which is contained inside a List. This abstraction brings great power because once you define such a type class, you can use it for any List type, be it List[String] or List[Int].

I always like to refer to the image drawn by Adriaan Moore in his paper "Genrics Of A Higher Kind":

Higher Kinds

What does the type parameter F really mean

Fs sole purpose is to define a contract with the implementer of the Functor. By the signature of F we can deduce what kind of type Functor expects. When we see that it has one "placeholder" ([_]) we know, by convention, that this means that F should take a single type parameter. If we think about all the types that take a single type parameter, we can see that there are many, for example List, Option, Try, Future, Task, etc.

For a more broad explanation regarding higher kinded types, see What is a higher kinded type in Scala?