There are two main reasons:

- Haskell lacks an inherent notion of subtyping, so in general variance is less relevant.
- Contravariance mostly appears where mutability is involved, so most data types in Haskell would simply be covariant and there’d be little value to distinguishing that explicitly.

However, the concepts do apply–for instance, the lifting operation performed by `fmap`

for `Functor`

instances is actually covariant; the terms co-/contravariance are used in Category Theory to talk about functors. The `contravariant`

package defines a type class for contravariant functors, and if you look at the instance list you’ll see why I said it’s much less common.

There are also places where the idea shows up implicitly, in how manual conversions work–the various numeric type classes define conversions to and from basic types like `Integer`

and `Rational`

, and the module `Data.List`

contains generic versions of some standard functions. If you look at the types of these generic versions you’ll see that `Integral`

constraints (giving `toInteger`

) are used on types in contravariant position, while `Num`

constraints (giving `fromInteger`

) are used for covariant position.