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

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

scala-covariance-syntax

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.

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:

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

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-contravariance

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.

scala-contravariance-syntax

Example:-
Write a Scala program to demo Scala Contravariant SubTyping technique.

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 Type Syntax Description
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.

By admin

Leave a Reply