def foo[T](x: T): T = x
foo(1) // How is this typed?
1. Typing foo
creates a type variable T?
foo[T?]
2. Typing foo[T?](1)
adds a constraint to T?
foo[T?](1) // T? >: Int
3. Instantiating T? = Int
respects the constraints
foo[Int](1)
def foo[T](…): RetType = …
foo[T?](…) // T? >: Lo <: Hi
.bar(…)
T?
right after typing foo[T?](…)
?T
appears in RetType
T appears |
Safe? | T? = |
nowhere | Yes | Lo (arbitrarily) |
covariantly | Yes | Lo |
contravariantly | Yes | Hi |
co- and contravariantly or invariantly |
No | ¯\_(ツ)_/¯ |