Questions tagged [contravariance]

Within the type system of a programming language, covariance and contravariance refers to the ordering of types from narrower to wider and their interchangeability or equivalence in certain situations (such as parameters, generics, and return types)

Within the type system of a programming language, a typing rule or a type conversion operator is:

covariant if it preserves the ordering, ≤, of types, which orders types from more specific to more generic;

contravariant if it reverses this ordering, which orders types from more generic to more specific;

invariant if neither of these applies.

These terms come from category theory, which has a general definition of covariance and contravariance that unifies the computer science definition of these terms with the definition used in vector spaces.

This distinction is important in considering argument and return types of methods in class hierarchies. In object-oriented languages such as Python, if class B is a subtype of class A, then all member functions of B must return the same or narrower set of types as A; the return type is said to be covariant. On the other hand, if the member functions of B take the same or broader set of arguments compared with the member functions of A, the argument type is said to be contravariant. The problem for instances of B is how to be perfectly substitutable for instances of A. The only way to guarantee type safety and substitutability is to be equally or more liberal than A on inputs, and to be equally or more strict than A on outputs. Note that not all programming languages guarantee both properties in every context, and that some are unnecessarily strict; they are said not to support covariance or contravariance in a given context; the behavior of some programming languages is discussed below.

Typical examples:

The operator which constructs array types from element types is usually covariant on the base type: since String ≤ Object then ArrayOf(String) ≤ ArrayOf(Object). Note that this is only correct (i.e. type safe) if the array is immutable; if insert and remove operators are permitted, then the insert operator is covariant (e.g. one can insert a String into an ArrayOf(Object)) and the remove operator is contravariant (e.g. one can remove an Object from an ArrayOf(String)). Since the mutators have conflicting variance, mutable arrays should be invariant on the base type.

Let f be a function with a parameter of type T and let g be a function with a parameter of type S, both with the same return type. If T ≤ S, then g ≤ f. g can replace f anywhere, since it cares less about the type of its parameter, and both return the same type. Because the subtype relation between the argument type and the functions is reversed, the function type is said to be contravariant on its argument type.

Let f be a function that returns a value of type T and let g be a function that returns a value of type S, both with the same parameter type. If T ≤ S, then f ≤ g. f can replace g anywhere, since it returns only a subset of all possible values returned by g, and both take the same argument. Because the subtype relation between the argument type and the functions is preserved, the function type is said to be covariant on its return type.

In object-oriented programming, substitution is also implicitly invoked by overriding methods in subclasses: the new method can be used where the old method was invoked in the original code. Programming languages vary widely on their allowed forms of overriding, and on the variance of overridden methods' types.

494 questions
157
votes
5 answers

Difference between Covariance & Contra-variance

I am having trouble understanding the difference between covariance and contravariance.
jane doe
  • 1,613
  • 3
  • 11
  • 7
154
votes
4 answers

Why covariance and contravariance do not support value type

IEnumerable is co-variant but it does not support value type, just only reference type. The below simple code is compiled successfully: IEnumerable strList = new List(); IEnumerable objList = strList; But changing from…
cuongle
  • 69,359
  • 26
  • 132
  • 196
148
votes
4 answers

Why doesn't the example compile, aka how does (co-, contra-, and in-) variance work?

Following on from this question, can someone explain the following in Scala: class Slot[+T] (var some: T) { // DOES NOT COMPILE // "COVARIANT parameter in CONTRAVARIANT position" } I understand the distinction between +T and T in the…
oxbow_lakes
  • 129,207
  • 53
  • 306
  • 443
127
votes
3 answers

Covariance, Invariance and Contravariance explained in plain English?

Today, I read some articles about Covariance, Contravariance (and Invariance) in Java. I read the English and German Wikipedia article, and some other blog posts and articles from IBM. But I'm still a little bit confused on what these exactly are…
anon
115
votes
2 answers

Problem understanding covariance contravariance with generics in C#

I can't understand why the following C# code doesn't compile. As you can see, I have a static generic method Something with an IEnumerable parameter (and T is constrained to be an IA interface), and this parameter can't be implicitly converted to…
BenLaz
  • 995
  • 1
  • 6
  • 8
106
votes
3 answers

Give examples of functions which demonstrate covariance and contravariance in the cases of both overloading and overriding in Java?

Please show a good example for covariance and contravariance in Java.
JavaUser
  • 22,494
  • 44
  • 98
  • 127
106
votes
2 answers

How is Generic Covariance & Contra-variance Implemented in C# 4.0?

I didn't attend PDC 2008, but I heard some news that C# 4.0 is announced to support Generic covariance and contra-variance. That is, List can be assigned to List. How could that be? In Jon Skeet's book C# in Depth, it is explained…
Morgan Cheng
  • 66,562
  • 63
  • 166
  • 223
87
votes
2 answers

Understanding Covariant and Contravariant interfaces in C#

I've come across these in a textbook I am reading on C#, but I am having difficulty understanding them, probably due to lack of context. Is there a good concise explanation of what they are and what they are useful for out there? Edit for…
NibblyPig
  • 46,891
  • 62
  • 180
  • 311
61
votes
3 answers

Why aren't there many discussions about co- and contra-variance in Haskell (as opposed to Scala or C#)?

I know what covariance and contravariance of types are. My question is why haven't I encountered discussion of these concepts yet in my study of Haskell (as opposed to, say, Scala)? It seems there is a fundamental difference in the way Haskell views…
ErikR
  • 50,049
  • 6
  • 66
  • 121
49
votes
3 answers

Generics : List is same as List?

I am just trying to understand the extends keyword in Java Generics. List means we can stuff any object in the List which IS A Animal then won't the following also mean the same thing: List Can someone help me know the…
peakit
  • 25,979
  • 25
  • 58
  • 77
48
votes
2 answers

Why does ReSharper suggest that I make type parameter T contravariant?

ReSharper suggests me to make type parameter T contravariant by changing this: interface IBusinessValidator where T: IEntity { void Validate(T entity); } Into this: interface IBusinessValidator where T: IEntity { void Validate(T…
Vu Nguyen
  • 3,245
  • 2
  • 17
  • 32
43
votes
4 answers

No warning or error (or runtime failure) when contravariance leads to ambiguity

First, remember that a .NET String is both IConvertible and ICloneable. Now, consider the following quite simple code: //contravariance "in" interface ICanEat where T : class { void Eat(T food); } class HungryWolf : ICanEat,…
Jeppe Stig Nielsen
  • 54,796
  • 9
  • 96
  • 154
42
votes
3 answers

Simple examples of co and contravariance

Could someone provide me simple C# examples of convariance, contravariance, invariance and contra-invariance (if such thing exists). All samples I've seen so far was just casting some object into System.Object.
Grant Smith
  • 755
  • 2
  • 6
  • 11
42
votes
5 answers

C# : Is Variance (Covariance / Contravariance) another word for Polymorphism?

I am trying to figure out the exact meaning of the words Covariance and Contravariance from several articles online and questions on StackOverflow, and from what I can understand, it's only another word for polymorphism. Am I correct with the above…
Andreas Grech
  • 98,643
  • 98
  • 284
  • 354
41
votes
2 answers

C# variance annotation of a type parameter, constrained to be value type

It is possible in C# to add variance annotation to type parameter, constrained to be value type: interface IFoo where T : struct { void Boo(T x); } Why is this allowed by compiler if variance annotation makes completely no sense in a such…
1
2 3
32 33