I came across this here:
This does not compile, because all type variables have to be fixed at the invocation site. Even if you “nail down” type B,
def foo[A](f: A => List[A], i: Int) = f(i)
…you get a type mismatch.
What actually is being tried to convey here?
It looks like A needs to be Int. What are you trying to do?
I am trying to use polymorphism concepts.
What they meant is that in general type
Int may not be the same thus the following code does not compile. One might have thought that type
A would be inferred to be an
Int by the compiler but it is not possible (unless you provide implicit conversion from
A of course).
They meant that you can’t do this.
def foo[B](f: [A]A => List[A], b: B) = f(b)
That would be rank-2 polymorphism, but Scala doesn’t have first-class rank higher than 1. Hence the header for that section, “Scala has rank-1 polymorphism”.
For comparison, in Haskell
foo :: (forall a. a -> [a]) -> b -> [b]
foo f b = f b
Scala lets you encode higher rank, though. With 2.12.4, Scalaz 7.2.19, kind-projector 0.9.4:
scala> import scalaz.Id.Id, scalaz.~>
scala> def toList[A](a: A) = List(a)
toList: [A](a: A)List[A]
scala> def foo[B](f: Id ~> List, b: B) = f(b)
foo: [B](f: scalaz.Id.Id ~> List, b: B)List[B]
scala> foo(Lambda[Id ~> List](toList(_)), 33)
res1: List[Int] = List(33)
[A]A => List[A] is written as
Id ~> List.