What does the property 'contravariant' or 'covariant' belong to: function, functor, class, type class, data type, function or method argument, function or method return value, generic type/collection or something else?
From a mathematics perspective, they're a property of mappings between two categories (called functors). I think part of the confusion us simple programmers have (aside from no knowledge of category theory) is that these words are used without explicitly stating what categories we're dealing with. In the case of typed functional programming (e.g. Haskell), we're usually thinking about functors as mappings from the category of types, where the morphisms are function types, back to itself. But in the object-oriented world, these words are usually used in the context of a category of types where the morphisms indicate a subtype relationship.
Type variable. Since data definitions can bind new type variables, it's necessary to consider variance there and in the resulting type constructor, too.
Variance is related to type parameters in type constructors.
For example, consider the -> function type constructor. It has two parameters, the input type and the output type. Examples of function types are int->int and bool->bool.
The first parameter of the -> constructor (the type of the input) is contravariant while the second (the type of the output) is covariant.
For another example, consider the type of a generic immutable list, List<T>. The T type parameter of the List constructor is covariant.
I’m a little surprised you only got two answers, because I’m pretty sure the answer depends on how you look at the problem. Mine is this:
A function has variance because the types of its inputs or outputs are in a hierarchy.
An object type system (or I suppose even a functor system?) with generics might leverage variance to make sure that the behavior of its own methods is consistent with the Substitution Principle (LSP).
And many people will tldr this into variance being the tool to give you a type system that is LSP compatible. But it’s all about the operations, consuming and emitting types.
I think like this too. Would only like to add that I believe a type parameter is *variant in relation to a function/method, not just by itself. That's why some people say "appears in a covariant position " and so on.