In math, we call it "variance" - as in invariance, contravariance, and covariance. They each refer to the character of a given functor between categories. A functor is covariant if a -> b maps to Fa -> Fb, contravariant if a -> b maps to Fb -> Fa, and invariant (otherwise known as exponential) if (a -> b) and (b -> a) map to Fa -> Fb.
Every example of variant functors follow these laws. It helps to say that every higher-kinded type which admits a type parameter (i.e. List, Array, Option, etc) can be seen as an instance of a Functor (in fact, in haskell, they are instances of the Functor Typeclass).
Variance is a statement about the functionality of containers given a pre-existing relationship between types they contain. In Math, keeping with the example set, the functor \pi_n : hTop* -> Grp is canonically covariant, while P: Set -> Set: s -> P(s), the powerset functor, is canonically contravariant.
In keeping with the Scala tradition, Option and List, which you can check obey the functor laws. For more info, see Scalaz or Cats.
I feel that the examples in math are easier to understand that in programming. For example:
- The integral of a function is invariant to additive changes of variable : \int f(a+x)dx = \int f(x)dx
- The mean of a distribution is contravariant to additive changes of variable : \int f(a+x)xdx = -a + \int f(x)xdx
- The mean of a distribution is covariant to shifts of the domain (same formula, because f(x-a) is a shift of size "a")
- The variance of a distribution is invariant to additive changes of variable
etc.