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
0
votes
1 answer

Partially applying generics for type constraints

I currently try to construct a generic interface that every (generic) class deriving it will have a method accepting a delegate that accepts the type parameter and returns another class of the same type, with only another type parameter. I tried the…
KanHar
  • 13
  • 3
0
votes
1 answer

Scala anonymous function genric variance issues

I'm on the road to learn Scala and I'm having a hard time understanding contravariants, covariants, invariance, etc. From Why doesn't the example compile, aka how does (co-, contra-, and in-) variance work? I have learned how functions can be…
Miles
  • 1
  • 1
0
votes
0 answers

What are the benefits of contravariance in JAVA

I'd like to ask what are the benefits of using contravariance in JAVA? Assume that we have two methods: public static void f1(List list, T item){ list.add(item); } public static void f2(List list, T…
Iza Marek
  • 251
  • 1
  • 6
0
votes
1 answer

Referencing the subtype within a trait in Scala

With the vast support for generics in Scala, what is the best way to achieve the following cyclic parameter bounds, where C in Command[A, C] is a subtype of itself (i.e. UserCommand or SystemCommand)? Note: I have omitted the lower/upper type bounds…
Lawrence Wagerfield
  • 6,471
  • 5
  • 42
  • 84
0
votes
1 answer

Why are these contravariant argument types considered safe?

I just learned in my programming languages class that "contravariant argument types would actually be safe, but they have not been found useful and are hence not supported in practical languages." Even though they are not supported, I am confused as…
norman
  • 5,128
  • 13
  • 44
  • 75
0
votes
1 answer

Is it Covariance and Contravariance related issue?

I have the following code: class Header where TItem : IItem { IEnumerable Item { get; set; } } class HeaderA : Header { public HeaderA(int a) {...} } class HeaderB : Header { public HeaderB(int b) {...} } interface…
ca9163d9
  • 27,283
  • 64
  • 210
  • 413
0
votes
1 answer

Covariance / Contravariance in C#

I have the following code: public interface IParameter { ParameterName Name { get; set; } } public interface IParameter : IParameter { T Value { get; set; } T LLimit { get; } T RLimit { get; } } public class IntegerParameter :…
-1
votes
1 answer

Java Generics PECS , add capture ? super cannot be applied to java.util.list

The issue of variance (particularly contravariance) has got me banging my head against the wall for a week. I have finally understood the theory, thanks to a couple of questions on here, and now as soon as I start working on it, I am getting errors…
user16422658
-1
votes
1 answer

C# cast from child with more specific generic to parent with less specific generic

I am trying to cast from a child with a specific generic to a parent with a more general generic. Take the following code: public class AParent { } public class AChild : AParent { } public interface IParent { public void func(T…
Montana
  • 482
  • 1
  • 4
  • 16
-1
votes
1 answer

What exactly does "covariant in T" and "contravariant in T" mean exactly in Scala?

I've just begun learning Scala, I'm going thru Odersky's course and I'm stuck on understanding variances. I am also referring to this blog - https://medium.com/@wiemzin/variances-in-scala-9c7d17af9dc4 I do not understand the examples where the…
Saturnian
  • 1,686
  • 6
  • 39
  • 65
-1
votes
1 answer

Java Generics - inferred type does not conform to equality constraint(s)

I was going through Java Generics and understanding type parameter bounds. In the below code, I'm unable to figure why the compiler reports an error for line 38 but not 41. If I change the type parameter bounds of the sort() method to
Ravi
  • 172
  • 2
  • 9
-1
votes
1 answer

Contravariance in practice - C#

I read recently about covariance and contravariance - little code example below: public class BaseClass{ public int x = 1; public static void print(BaseClass objClass) { Console.WriteLine(objClass.GetType().Name + " " +…
Hadrian
  • 55
  • 1
  • 7
-2
votes
0 answers

Why doesn't the C# compiler allow assigning a method that takes an object parameter to an Action that expects an int parameter?

From what I understand about contravariance in C#, is that it is valid to assign a method that takes a more general type (base type) to a delegate that expects a less general type (derived type). For example, if we define a method that takes an…
-3
votes
1 answer

Can someone explain why this operation is invalid?

I was reading up on covariance and contravariance today and I came across a post on stack exchange where Jon Skeet was explaining invariance at the class level. He used an example of fruit and why allowing covariance at that level would be a bad…
elucid8
  • 1,412
  • 4
  • 19
  • 40
-4
votes
2 answers

Java vs Smalltalk - covarince and contravariance

Does Smalltalk support covariance and contravariance? Do these concepts apply to this language?
1 2 3
35
36