Tom - 2 months ago 11

Scala Question

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`

`F`

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":

What does the type parameter F really mean

`F`

s 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?