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.

540 questions
7
votes
1 answer

Java type variance, consumer of generic type

I am struggling to understand how variance works in Java. In the following example, I define a function test which takes a Consumer. The function is defined without contravariance, so I would expect that Consumer is not a subtype of…
asp
  • 221
  • 2
  • 7
7
votes
3 answers

Covariance in delegate, any example?

I'm reading this msdn article, the contravariance example (keyboard and mouse event) is great and useful, while the covariance example (Mammal and Dog) doesn't look so. The keyboard and mouse event is great since you can use 1 handler for multiple…
Marson Mao
  • 2,935
  • 6
  • 30
  • 45
7
votes
2 answers

Contravariant Delegates Value Types

Can anyone shed light on why contravariance does not work with C# value types? The below does not work private delegate Asset AssetDelegate(int m); internal string DoMe() { AssetDelegate aw = new AssetDelegate(DelegateMethod); aw(32); …
Jack Kada
  • 24,474
  • 29
  • 82
  • 106
7
votes
6 answers

Why the concept of "Covariance" and "Contravariance" are applicable while implementing the methods of an interface?

The use case is some what like this: public class SomeClass : ICloneable { // Some Code // Implementing interface method public object Clone() { // Some Clonning Code } } Now my question is Why is it not possible to use…
Amit
  • 1,007
  • 5
  • 13
  • 19
7
votes
1 answer

Contravariance? Covariance? What's wrong with this generic architecture...?

I'm having some problems setting up a command handling architecture. I want to be able to create a number of different commands derived from ICommand; then, create a number of different command handlers derived from ICommandHandler; Here's the…
Sambo
  • 1,472
  • 5
  • 21
  • 33
7
votes
1 answer

Invariance, covariance and contravariance in Java

Java lesson on generics are leading me to variance concept. This causes me some headaches as I cannot find a very simple demonstration of what it is. I have read several similar questions on stackoverflow, but I found them too difficult to…
mins
  • 6,478
  • 12
  • 56
  • 75
7
votes
3 answers

What's a common programming use of contra-variance?

I've read the following post on contra variance and Lasse V. Karlsen's answer: Understanding Covariant and Contravariant interfaces in C# Even though I understand the concept, I don't get why it's useful. For example, why would anyone make a read…
matanc1
  • 6,525
  • 6
  • 37
  • 57
7
votes
3 answers

Covariance and Contravariance - Just different mechanisms for invoking guaranteed base class behavior?

I'm having a struggle understanding these two concepts. But I think after many videos and SO QA's, I have it distilled down to its simplest form: Covariant - Assumes a sub-type can do what its base-type does. Contravariant - Assumes you can treat a…
richard
  • 12,263
  • 23
  • 95
  • 151
6
votes
3 answers

How is the datatype of type parameter decided in covariance and contravariance?

I was reading the book Java Generics and Collections By Maurice Naftalin, Philip Wadler, and within the first two chapters I ended up in having my head messed up with doubts. I was not able to figure out the answers. In the call: public static
Dipesh Gupta
  • 787
  • 1
  • 7
  • 20
6
votes
3 answers

Type variance in .NET Framework 4.0

IEnumerable, IComparable and a few more are now type-variant. IList, ICollection and many others aren't. Why?
UserControl
  • 14,766
  • 20
  • 100
  • 187
6
votes
1 answer

Covariance of Box in rust

I have a function that expects a short lived object. I would expect that I would be able to always pass it a long lived object. But I am getting a strange error when I try to encode that: type F<'arg> = Box; fn…
fakedrake
  • 6,528
  • 8
  • 41
  • 64
6
votes
1 answer

.NET: Covariance and Contravariance

Possible Duplicate: Difference between Covariance & Contra-variance I'm trying to understand what covariance and contravariance is, as well as the difference between the two. I have looked at this link, and so far I have understood the…
Nahydrin
  • 13,197
  • 12
  • 59
  • 101
6
votes
0 answers

In scala, how could a covariant type parameter be an upper bound of an abstract type, but not another invariant type parameter?

The following code demonstrates it clearly: trait Poly1Group[-IUB, +OUB] { trait Case[-I <: IUB] { type Out <: OUB // <------------------------------- success def apply(v: I): Out } trait ==>[ -I <: IUB, O <: OUB…
tribbloid
  • 4,026
  • 14
  • 64
  • 103
6
votes
3 answers

Benefits of contravariance in IComparer & IEqualityComparer interfaces

On the msdn page on contravariance I find a quite interesting example that shows "benefits of contravariance in IComparer" First they use a fairly odd base & derived classes: public class Person { public string FirstName { get; set; } public…
Valentin Kuzub
  • 11,703
  • 7
  • 56
  • 93
6
votes
3 answers

Why can't List be replaced with List?

Consider the following code: public class Main { static class Animal {} static class Dog extends Animal {} static List foo() { List dogs = new ArrayList<>(); return dogs; } public static…
IsaacLevon
  • 2,260
  • 4
  • 41
  • 83