Please consider the following 2 lines of code:
def foo[F[B],A](fa: F[A]): String = fa.toString
println(foo(10))
It prints 10. What I wonder, is how it even compiles. I am trying to understand how Scala resolves the generics here. I mean, what are A, B, and F?
When looking at Intellij, it seems like 10 is converted from a Scala Int, to a Java Integer. But I don't know how the Java Integer is converted to any F[A] (Java Integer is not a generic type), as foo expects to receive.
how the Java Integer is converted to any F[A](Java Integer is not generic type), as foo expects to receive.
Java Integer is subtype of Comparable[Integer]
public final class Integer extends Number implements Comparable<Integer>
Scala 2.13 infers F = Any and A = Nothing
scala> def foo[F[_],A](fa: F[A]) = fa
def foo[F[_], A](fa: F[A]): F[A]
scala> foo(10) // print
foo[Any, Nothing](10) // : Any
scala> foo(10)
val res9: Any = 10
This inference happens because of the presence of implicit conversion
implicit def int2Integer(x: Int): java.lang.Integer = x.asInstanceOf[java.lang.Integer]
If we hide this conversion it will not compile
scala> implicit val int2Integer = null
val int2Integer: Null = null
scala> foo(10)
^
error: no type parameters for method foo: (fa: F[A]): F[A] exist so that it can be applied to arguments (Int)
--- because ---
argument expression's type is not compatible with formal parameter type;
found : 10
required: ?F[?A]
^
error: type mismatch;
found : Int(10)
required: F[A]
However note despite the fact that int2Integer made it compile, the implicit conversion did not actually take place (which might be a bug)
scala> foo(10)
val res9: Any = 10
where res9 should have been typed as Comparable[Integer] instead of Any.
Scala 3 (Dotty) infers F = Comparable and A = Integer as per -Xprint:typer
foo[Comparable, Integer](int2Integer(10))
and the implicit conversion is indeed applied
Starting dotty REPL...
scala> def foo[F[_],A](fa: F[A]) = fa
def foo[F[_$1], A](fa: F[A]): F[A]
scala> foo(10)
val res0: Comparable[Integer] = 10
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With