If you have 2 classes A,B such that A is subtype of B, and
if you have 2 parameterized types C[A],C[B] such that C[A] is subtype of C[B] then C is said to be covariant
if you have 2 parameterized types C[A],C[B] such that C[A] is subtype of C[B] then C is said to be covariant
Examples
Immutable List and Queue are examples of covariant Types in scala libraries.
Immutable List and Queue are examples of covariant Types in scala libraries.
1
2
3
| sealed abstract class List[+A] extends ......... class Queue[+A] extends ........ |
Covariance is indicated by notation + on type parameter passed
Immutablity and Covariance
If you notice in api-docs covariance is generally associated with immutable types , eg scala.collection.immutable.Queue, scala.collection.immutable.List
There is a very good reason for this. From designers perspective, there were 2 reasons where covariance relation could fail
- Re-Assignment of values. Classic example being java array reassignment problem, resulting in ArrayStore exception
- Passing generic type as a parameter in method.
Thus to avoid above pitfalls , covariant types are immutable
If you have 2 classes A, B such that A is subtype of B, and
if you have 2 parametrized Types C[A], C[B] such that C[B] is subtype of C[A] then C is said to be contravariant
if you have 2 parametrized Types C[A], C[B] such that C[B] is subtype of C[A] then C is said to be contravariant
Examples
OuputChannel trait from scala api is example of contravariant type
OuputChannel trait from scala api is example of contravariant type
1
| trait OutputChannel[-Msg] extends AnyRef |
Contravariance is indicated by notation – on type parameter passed.
*** Function parameters are contravariant ***
*** Function’s return value type is covariant ***
*** Function’s return value type is covariant ***
Variance
Scala’s type system has to account for class hierarchies together with polymorphism. Class hierarchies allow the expression of subtype relationships. A central question that comes up when mixing OO with polymorphism is: if T’ is a subclass of T, is Container[T’] considered a subclass of Container[T]? Variance annotations allow you to express the following relationships between class hierarchies & polymorphic types:
Meaning | Scala notation | |
covariant | C[T’] is a subclass of C[T] | [+T] |
contravariant | C[T] is a subclass of C[T’] | [-T] |
invariant | C[T] and C[T’] are not related | [T] |
The subtype relationship really means: for a given type T, if T’ is a subtype, can you substitute it?
scala> class Covariant[+A]
defined class Covariant
scala> val cv: Covariant[AnyRef] = new Covariant[String]
cv: Covariant[AnyRef] = Covariant@4035acf6
scala> val cv: Covariant[String] = new Covariant[AnyRef]
:6: error: type mismatch;
found : Covariant[AnyRef]
required: Covariant[String]
val cv: Covariant[String] = new Covariant[AnyRef]
^
No comments:
Post a Comment