I see this sentence is scala specification (pdf):
The variance position of a method parameter is the opposite of the variance position of the enclosing parameter clause.
Which is on page 44.
But I can't quite understand it. Could you give me some samples?
So, let's start with a motivating example. Suppose I write the following:
class Foo[+A] {
def foo(a : A) = ???
}
Now, by annotating the type parameter A
with a +
, I've declared that Foo
is covariant in A
, which is to say that if X <: Y
, then Foo[X] <: Foo[Y]
. So, suppose I have such a Foo[X]
and I try to pass it to a function which requires a Foo[Y]
:
def bar(a : Y, x : Foo[Y]) = {
x.foo(a)
}
Now, bar
tries to call x.foo
with a Y
. But x
is a Foo[X]
, and X
is a subtype of Y
- so it's like trying to pass an Object
to a function requiring a String
- there's no guarantee that the Object
contains everything that's needed to do this. So the definition of Foo
above is invalid - to use the terminology in the specification, the type parameter A
is covariant, but you've attempted to use it in a contravariant position - as the parameter to a function.
The set of rules set out in the Scala spec where you've referenced are the rules used by the Scala compiler to determine the variance position of different places in the code, which it uses to check that you haven't done anything like the definition of Foo
above. The specific clause you identify gives the rule corresponding to the example above - it says that the variance position of a parameter clause (e.g. within the parameter list of a function) is the opposite of the surrounding variance position.
Usually, this means that parameter clauses are contravariant. However, things can get multiply inverted:
class Foo[A, B] {
def foo(a : A) = {
def bar(b : B) = ???
}
}
Here, the parameter clause of foo
is contravariant, and hence the parameter clause of bar
is inverted again, and is covariant. So the following definition is valid:
class Foo[-A, +B] {
def foo(a : A) = {
def bar(b : B) = ???
}
}
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