- Let
C<A>
be a higher-kinded type e.g. inList<Animal>
,List
isC
andAnimal
isA
. - Let
S
be a subtype ofT
e.g. inclass Cat extends Animal
,Cat
isS
andAnimal
isT
- If
C<S>
is a subtype ofC<T>
, thenC
is covaraint onT
e.g.List<Cat>
is a subtype ofList<Animal>
- If
C<T>
is a subtype ofC<S>
, thenC
is contravariant onT
e.g.Predicate<Animal>
is a subtype ofPredicate<Cat>
- If neither
C<T>
and norC<S>
are subtypes of the other, thenC
is invariant onT
- If both
C<T>
andC<S>
are subtypes of each other, thenC
is phantom variant onT
. This is possible in languages which support phantom types like Haskell
In Scala: