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

On covariance and contravariance

Scenario is public interface IRow { int Id { get; set; } string Name { get; set; } } public class ARow : IRow { ... } public class BRow : IRow { ... } public class RowCollection : Collection where T : IRow { } public interface…
sanoj
  • 1
  • 1
0
votes
0 answers

Which Collections types are Covariant and Contravariant in C# and VB.net

Ok, I know that IEnumerable is covariant. But outside of that one, I'm not sure which other ones are covariant and contravariant. The only way I can think to figure it out is to go through each and every type and look at the definition. I think it…
jacob p
  • 31
  • 1
  • 4
0
votes
1 answer

Compound types, contra variance, etc. in Scala

I'm working on some fairly generic code (yet another CSV file reader) and I've run into some trouble with contravariance. I've stripped the code down to something that I think demonstrates the problem here (I copied this from my Scala…
Phasmid
  • 923
  • 7
  • 19
0
votes
1 answer

Contravariance problems with event properties

Suppose I have a simple EventArgs subclass: class MyArgs : EventArgs { } Consider I have two classes with events: class MyData { public event EventHandler Method; } class MyObject { public event EventHandler Method; } And a simple…
benjamin.popp
  • 547
  • 1
  • 6
  • 20
0
votes
1 answer

In Expression, parameters of TDelegate are not contravariant, ways around?

I've recently run into an issue dealing with the contravariance of a function's parameters in C#, and how that isn't honored as soon as an Expression is wrapped around that function. Here's an example of what I'm talking about: class BaseClass { …
Tom E.
  • 13
  • 5
0
votes
1 answer

Defining Contravariant add method on Immutable Stack in Java

I've been trying to define an immutable ConsList in Java, somewhat like how Lists work in Scala. Each prepending creates a new view of the list (starting with the new head) and returns it. Here's what I have so far, which all compiles and runs…
Mshnik
  • 7,032
  • 1
  • 25
  • 38
0
votes
2 answers

Covariance Contravariance Generics Interfaces - why doesn't this work?

Thank you in advance. Here is my code: public class ApplicationUser : IdentityUser { public ApplicationUser() { } } public class AppUserManager : UserManager { ... } public interface IOwinManager { …
0
votes
3 answers

Contravariance in Generics C#

I don't know who resolve this segment code with variance: I have an abstract father class: public abstract class PdfObject {...} And two child classes: public class PdfText : PdfObject {...} public class PdfImage : PdfObject {...} Now, my wrong…
darkmaku
  • 13
  • 3
0
votes
2 answers

In Scala, what should be the type of a map from string to case class, and a map from string to functions taking those case classes as input parameter?

The scenario I am trying to model is as follows. I have a couple of case classes that differ in their parameters, but they all extend the trait Entity. // case classes trait Entity case class E1(..params..) extends Entity case class E2(..params..)…
Mahdi
  • 1,778
  • 1
  • 21
  • 35
0
votes
1 answer

Difference in ability to use contravariance when using a Func parameter

I am curious as to why the following logic is allowed in C# private static void Foo(Func func) { try { // ... } catch (ArgumentException ex) { func(ex); } } whereas this is not private…
Phil Gref
  • 987
  • 8
  • 19
0
votes
2 answers

Is there a difference in scala type bound notation direction?

Is there a difference in scala type bound notation direction, as in is [B <: A] the same as [A >: B]?
Caballero
  • 11,546
  • 22
  • 103
  • 163
0
votes
1 answer

Basic FunctionN cov/contravariance

I have pretty much a code organized like this: class Person(name: String, val addr: Int) { def distance(that: Person) = this.addr - that.addr } class Employee(_name: String, role: String, _addr: Int) extends Person(_name, _addr) { def smgth =…
NoIdeaHowToFixThis
  • 4,484
  • 2
  • 34
  • 69
0
votes
1 answer

Covariance and Contravariance conversion fails

I know I'm missing something, but shouldn't this work!? public interface IFoo where TA : class where TB : class { } public class Foo : IFoo where T : class { } public class Whatever { } ... Foo _Foo = new…
James Wilkins
  • 6,836
  • 3
  • 48
  • 73
0
votes
1 answer

Casting Generic to abstract base - covariance

The code below gives compile time error: Error 170 Cannot convert type 'Tests.ChangeListener' to 'Tests.BaseListener' How do I get this to compile? namespace Tests { [TestClass] public class UnitTest1 { [TestMethod] …
LL020
  • 55
  • 4
0
votes
3 answers

Covariance and contravariance usage in C#

I'm trying to achieve something that I'm not sure is possible and I'm a bit stuck. I have some base types called Client and Server defined like this: public class Client { } public class Server where ClientTemplate :…
Sanctus2099
  • 1,669
  • 5
  • 22
  • 40