platypus - 1 year ago 59
Scala Question

# variance annotation, keeping track "positive" and "negative" positions by Scala compiler

In Programming in Scala page 436, the author gives an example of the compiler checking that each type parameter is only used in positions that are classified appropriately.

abstract class Cat[-T, +U] {
def meow[W^-](volume: T^-, listener: Cat[U^+, T^-]^-) : Cat[Cat[U^+, T^-]^-, U^+]^+
}

How does the example work out? Why do W and the first T get a negative sign? How does the algorithm actually work?

http://www.artima.com/pins1ed/type-parameterization.html

19.4 in 1st ed.

"Method value parameter positions are classified to the flipped classification relative to positions outside the method."

"Besides method value parameter positions, the current classification is also flipped at the type parameters of methods."

Flipped in this case means "flipped from positive", hence, negative.

For bonus points, generate a LOLcats that illustrates a physical interpretation of this model.

Okay let's look at the 3rd value parameter "listener".

It has a annotation of: Cat[U^+, T^-]^-.

Why does U have +? Why does T have -? Why does the whole thing have a -?

The method param is a contravariant position, hence the outermost (right-most) minus.

The type params to Cat are [-T, +U], so in this flipped position, [+, -]. (The actual params being applied, [U, T], aren't relevant.) It checks because the actual params are co- and contra-variant, respectively.

More questions:

Could you kindly describe on SO why the return value type has the following annotation
for the sake of completeness...

Also could you be so kind as to give an example of the following rule?

A classification is sometimes flipped at the type argument position of a type...

This second additional question is the same as your previous first additional question. The two Cat[+,-] illustrate flipping, and the result type Cat[-,+] illustrates not flipping.

This thread provides further motivation for variance of params (things you pass in) and results (things you get out):