Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize covariant variable?

class C [+T] { var v : T = _ }

compiler error: covariant type T occurs in contravariant position in type T of value value_=

why? how can I fix it?

like image 250
rastafarra Avatar asked Dec 12 '11 11:12

rastafarra


3 Answers

You can declare it as private[this]:

class C [+T] { private[this] var v : T = _ }

Any usage you try that this scope does not allow would be unsafe with a co-variant T.

like image 129
Daniel C. Sobral Avatar answered Nov 09 '22 22:11

Daniel C. Sobral


You cannot have a var of a covariant type. A var amounts to having, among other things, a public def v_=(newV: T), so it makes T appears as a routine argument, which is a contravariant position. So you must either

  • renounce covariance and declare C[T] rather than C[+T]
  • make v a val

To be a little more verbose on the "why" part of your question, by making T is covariant parameter with +T, you states that you wants C[B] to a a subtype of C[A] if B is a subtype of A. This means you want to allows :

val cb: C[B] = new C[B]
val ca : C[A] = cb    

To makes this sounds, the compiler restricts where T may appear in C. To make it short and with minor simplifications, v cannot appear as parameter of a routine (or as the type of a var). Otherwise, after you have initialized cb and ca as described above you coulddo

ca.v = new A

This would be allowed, as ca is supposed to be a C[A], so its variable v is of type A. However, as C is covariant in T, ca may (and does in the example) reference a C[B] instance. Would this assignment be allowed, you could then do

val vInCb: B = cb.v

confident that this gives you a B. However, you just put an A there through the ca reference. This situation must be forbidden, and it is, by forbidding covariant type parameter T as the type of a var.

like image 41
Didier Dupont Avatar answered Nov 09 '22 22:11

Didier Dupont


You have to make it a val. A var always has a setter method where the type appears in contravariant position.

like image 45
Kim Stebel Avatar answered Nov 09 '22 23:11

Kim Stebel