Help to understand this?


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 A and 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 Int to 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.~>
import scalaz.Id.Id
import scalaz.$tilde$greater

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)

Here [A]A => List[A] is written as Id ~> List.