What are covariance and contravariance?
Covariance and contravariance are just monotonicity and anti-monotonicity, applied to types ordered by subtyping.That is: if we have a function on types, say, the function `f` defined by:    f(x) = Int -> x

Then we say `f` is covariant because it is monotone: it preserves the subtype ordering on its argument. That is:    if x <: y, then f(x) <: f(y)

Similarly, if we consider `f` defined by:    f(x) = x -> Int

then this `f` is contravariant because it is anti-monotone: it reverses the subtype ordering on its argument. That is:    if x <: y, then f(y) <: f(x)

People tend to find covariance more intuitive than contravariance; unless the issue is pointed out, they tend to assume everything is covariant. They see a type, say:    dog -> dog

and they assume "oh, every dog is an animal, so I can put 'animal' in place of 'dog' and it'll be more general (i.e. a supertype)". This is false, as the article points out.