I'm reading about higher kinded types in Scala and I can't wrap my head around the use of the underscore.
For example:
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B) : F[B]
}
val listFunctor = new Functor[List] {
override def map[A, B](fa: List[A])(f: A => B) = fa.map(f)
}
listFunctor.map(List(1,2,3))(_ + 3)
If I use a parametrised type A in the trait, I get the same result:
trait Functor2[F[A]] {
def map[A, B](fa: F[A])(f: A => B) : F[B]
}
val listFunctor2 = new Functor2[List] {
override def map[A, B](fa: List[A])(f: A => B) = fa.map(f)
}
listFunctor2.map(List(1,2,3))(_ + 3)
Is there a significant difference between the two examples?
A
comes frommap[A, B]
. The one defined inF[A]
is a different one. It's just a placeholder. And it can't be used outside of the signature. In general, a higher-kinded type is just a type which takes another type as an argument. Syntax isn't so important. – Pavel S.