Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are all invariant generic class positions invariant in type parameter lists in Scala?

I'm a bit perplexed by the strictness of the typechecker below — it seems that the invariant T position of Inv[T] is also invariant within Variantish's parameter list:

scala> class Inv[T]
defined class Inv

scala> class Variantish[+T, +TVar <: Inv[T]]
<console>:12: error: covariant type T occurs in invariant position in type  <: Inv[T] of type TVar
       class Variantish[+T, +TVar <: Inv[T]]
                             ^

Variant types can normally occur in what look like invariant argument-list positions legally, e.g. with object-protected visibility:

class Variantish[+T](protected[this] var v: Inv[T])

and it seems that the following would be just as typesafe:

class Variantish[+T, +TVar <: Inv[T]](protected[this] var v: TVar)

Need that check mentioned above be so strict?

like image 577
concat Avatar asked Nov 08 '22 23:11

concat


1 Answers

From the language specification (emphasis mine), about conformance (ie T' is a super-type of T):

Type constructors T and T′ follow a similar discipline. We characterize T and T′ by their type parameter clauses [a1,…,an] and [a′1,…,a′n], where an ai or a′i may include a variance annotation, a higher-order type parameter clause, and bounds. Then, T conforms to T′ if any list [t1,…,tn] -- with declared variances, bounds and higher-order type parameter clauses -- of valid type arguments for T′ is also a valid list of type arguments for T and T[t1,…,tn]<:T′[t1,…,tn].

This is really difficult to understand (IMHO), but I believe it means that for Variantish to be covariant in T, you would have to be able to write

Variantish[Dog, TVar] <: Variantish[Animal, TVar]

for any TVar for which Variantish[Animal, TVar] makes sense. But this doesn't even make sense (let alone have any truth value) for some of those TVar, such as Inv[Animal]. That's why it is forbidden in that place.

like image 160
Cyrille Corpet Avatar answered Nov 15 '22 13:11

Cyrille Corpet