Reputation: 41909
Scala in Depth presents the following variance example.
scala> trait Function[-Arg, +Return] {
| def apply(arg: Arg): Return
| }
defined trait Function
scala> val foo = new Function[Any, String] {
| override def apply(arg: Any): String =
| "Hello. I received " + arg
| }
foo: Function[Any,String] = $anon$1@5db0e244
scala> val bar: Function[String, Any] = foo
bar: Function[String,Any] = $anon$1@5db0e244
What's the reason that we can assign foo
to bar
? I have a rough idea, but figured I'd ask outright.
Upvotes: 0
Views: 92
Reputation: 26486
Exactly because the variance annotations make Function[Any, String]
a subtype of Function[String, Any]
.
The covariance annotation, +
means a narrower type argument yields a narrower constructed type and the contravariance annotation -
, means a wider type parameter yields a narrower constructed type.
Upvotes: 3