Scala Variances: Covariant, Invariant and Contravariant

Filed Under: Scala

In this post, we are going to discuss about Scala Variance and it’s use cases.

What is Variance?

Variance defines Inheritance relationships of Parameterized Types. Variance is all about Sub-Typing.

Please go through the following image to understand “What is Parameterized Type”.


Here T is known as “Type Parameter” and List[T] is known as Generic.

For List[T], if we use List[Int], List[AnyVal], etc. then these List[Int] and List[AnyVal] are known as “Parameterized Types”

Variance defines Inheritance relationship between these Parameterized Types.

Advantage of Variance in Scala

The main advantage of Scala Variance is:

  • Variance makes Scala collections more Type-Safe.
  • Variance gives more flexible development.
  • Scala Variance gives us a technique to develop Reliable Applications.

Types of Variance in Scala

Scala supports the following three kinds of Variance.

  • Covariant
  • Invariant
  • Contravariant

We will discuss these three variances in detail in coming sections.

Covariant in Scala

If “S” is subtype of “T” then List[S] is is a subtype of List[T].

This kind of Inheritance Relationship between two Parameterized Types is known as “Covariant


Scala Covariance Syntax:-
To represent Covariance relationship between two Parameterized Types, Scala uses the following syntax:
Prefixing Type Parameter with “+” symbol defines Covariance in Scala.


Here T is a Type Parameter and “+” symbol defines Scala Covariance.

NOTE:- For simplicity reason, I’m using “List” here. However it may be any valid Scala Type like Set[+T], Ordered[+T] etc.

Write a Scala program to demo Scala Covariant SubTyping technique.

class Animal[+T](val animial:T)

class Dog
class Puppy extends Dog

class AnimalCarer(val dog:Animal[Dog])

object ScalaCovarianceTest{
  def main(args: Array[String]) {
    val puppy = new Puppy
    val dog = new Dog

    val puppyAnimal:Animal[Puppy] = new Animal[Puppy](puppy)
    val dogAnimal:Animal[Dog] = new Animal[Dog](dog)

    val dogCarer = new AnimalCarer(dogAnimal)
    val puppyCarer = new AnimalCarer(puppyAnimal)


NOTE:- As Animal class is defined by using Variance Annotation i.e. “+T”, we can pass either dogAnimal or its subtype puppyAnimal to create a AnimalCarer object.

If we remove Variance Annotation in Animal class definition, like as shown below:

class Animal[T](val animial:T)
// Remaining code is same as above.

It wont compile. We will get the following compilation error message:

Type mismatch, expected: Animal[Dog], found: Animal[Puppy]

To solve these kind of problems, we should use Scala Covariance.

As per this example, we can say the following Scala Covariance:

“As Puppy is subtype of Dog, Animal[Puppy] is a subtype of Animal[Dog]. We can use Animal[Puppy] where we require Animal[Dog].” This is know as Scala Covariance.

Contravariant in Scala

If “S” is subtype of “T” then List[T] is is a subtype of List[S].

This kind of Inheritance Relationship between two Parameterized Types is known as “Contravariant


Scala Contravariant Syntax:
To represent Contravariant relationship between two Parameterized Types, Scala uses the following syntax:
Prefixing Type Parameter with “-” symbol defines Contravariant in Scala.


Write a Scala program to demo Scala Contravariant SubTyping technique.

abstract class Type [-T]{
  def typeName : Unit

class SuperType extends Type[AnyVal]{
  override def typeName: Unit = {
class SubType extends Type[Int]{
  override def typeName: Unit = {

class TypeCarer{
  def display(t: Type[Int]){

object ScalaContravarianceTest {

  def main(args: Array[String]) {
    val superType = new SuperType
    val subType = new SubType

    val typeCarer = new TypeCarer



As we define Contravariance in Type[-T], it works well. TypeCarer.display() is defined with Type[Int] i.e. SubType, but still it accepts Type[AnyVal] because Scala Contravariance subtyping.

If we remove “-” definition in Type like “Type[T]”, then we will get compilation error.

Invariant in Scala

If “S” is subtype of “T” then List[S] and List[T] don’t have Inheritance Relationship or Sub-Typing. That means both are unrelated.

This kind of Relationship between two Parameterized Types is known as “Invariant or Non-Variant

In Scala, by default Generic Types have Non-Variant relationship. If we define Parameterized Types without using “+’ or “-” symbols, then they are known as Invariants.

What is Variance Annotation in Scala?

Variance Annotation means defining “+” or “-” before Type Parameters.

+T and – T are know as Variance Annotations in Scala.

Scala Variance Summary

In this section, we are going to summarize all 3 concepts we have discussed about Scala Variance Types in above sections.

Scala Variance TypeSyntaxDescription
Covariant[+T]If S is subtype of T, then List[S] is also subtype of List[T]
Contravariant[-T]If S is subtype of T, then List[T] is also subtype of List[S]
Invariant[T]If S is subtype of T, then List[S] and List[T] are unrelated.

That’s it all about Scala Variance. We will discuss some more Scala concepts in my coming posts.

Please drop me a comment if you like my post or have any issues/suggestions.


  1. Rakesh says:

    Whats the error in the below code ?
    //contra variance
    class Animal1[-T](val animal: T)

    class AnimalCareer1(val dog1: Animal1[Puppy1])

    class Dog1
    class Puppy1 extends Dog1

    object AbcOnj1 extends App {

    val dog1 = new Animal1(new Dog1)
    val puppy1 = new Animal1(new Puppy1)

    val dogcareer = new AnimalCareer1(dog1)
    val puppycareer = new AnimalCareer1(puppy1)


  2. Shyam says:

    Really nice ,,,thanks

  3. Raj says:

    This is really wonderful make it easier to understand to anyone.

  4. Niraj says:

    Nice Post. Explained it very clearly using images.

  5. Arnold Higyed says:

    Thank you! Great post!

  6. Krishna Chowdary Garapati says:

    Good explanation. I am a Java developer. Better if you compare the topics with java, we can easily understand.

  7. Vinit S says:

    Nice post. Explained it very clearly.

  8. gayatri gupta says:

    Excellent post

  9. Aamir says:

    Best Post on Scala Generics I have read.

  10. Aniruddha Sinha says:

    You may find this example interesting on Covariance and Contravariance
    type AnimalCovariance[+T]
    type Dog
    type Puppy <: Dog
    type dogs=AnimalCovariance[Dog]
    type puppies=AnimalCovariance[Puppy]
    //test of covariance

    type AnimalContravariance[-T]
    type Dog2
    type Puppy2<:Dog2
    type dogs2=AnimalContravariance[Dog2]
    type puppies2=AnimalContravariance[Puppy2]
    //test for contravariance

Leave a Reply

Your email address will not be published. Required fields are marked *

Generic selectors
Exact matches only
Search in title
Search in content