# 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.

Example:-
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)

println("Done.")
}
}
``````

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.

Example:-
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 = {
println("SuperType")
}
}
class SubType extends Type[Int]{
override def typeName: Unit = {
println("SubType")
}
}

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

object ScalaContravarianceTest {

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

val typeCarer = new TypeCarer

typeCarer.display(subType)
typeCarer.display(superType)
}

}
``````

NOTE:-
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.

Example:-
+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
//COVARIANCE
type AnimalCovariance[+T]
type Dog
type Puppy <: Dog
type dogs=AnimalCovariance[Dog]
type puppies=AnimalCovariance[Puppy]
//test of covariance
implicitly[Puppy<:<Dog]
implicitly[puppies<:<dogs]

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

close
Generic selectors
Exact matches only
Search in title
Search in content