TypeSafe Journey Using Scala
  • Table Of Content
  • About This Book
  • Copyleft Notice
  • Thanks
  • My Journey
  • Introduction
  • Phase I: Basics
    • Chapter 1: What are the types?
    • Chapter 2: Types Vs Classes and Subtyping Vs Inheritance
    • Chapter 3: Type Disciplines
    • Chapter 4: Type Inference
    • Chapter 5: Scala Types Hierarchy
    • Chapter 6: Parameterized Types
    • Chapter 7: Type Erasure
    • Chapter 8: Type Classes and Ad-hoc Polymorphism
    • Chapter 9: Type Constraints
    • Chapter 10: Variance
      • Non-Variance
      • Co-Variance
      • Contra-Varaince
      • Conclusion
  • Phase II: Advance
    • Chapter 11: What are Kinds in Scala?
    • Chapter 12: Higher Kinded Types
Powered by GitBook
On this page
  1. Phase I: Basics

Chapter 10: Variance

PreviousChapter 9: Type ConstraintsNextNon-Variance

Last updated 6 years ago

Variance in Scala is the most interesting and complex topic. The complexity of variance completely depends on the way of explaining. The concept of variance depends on the inheritance between parameterized types. Let’s take an example from , where we create new parameterize types using type constructor as below:

class Java 
class Scala

trait Book[T] { … }

new Book[Java]{} // creates new type Book of Java
new Book[Scala]{} // creates a new type Book of Scala

As we explained earlier, via type constructor we are creating new parameterize types of books like Book[Java] and Book[Scala]. We know, Book[Java] is a completely different type than Book[Scala], but what if requires relationship between two parameterized types like below:

class Car
class Lamborghini extends Car
class Jaguar extends Car

trait Garage[Car]

new Garage[Lamborghini]
new Garage[Jaguar]

In the above example, we are creating Car class hierarchy and Garage[T] type which accepts type parameter. By using Car hierarchy, we are creating two new types Garage[Lamborghini] (Garage of Lamborghini) and Garage[Jaguar] (Garage of Jaguar) and those types are completely independent of each other. But as per our code, Lamborghini and Jaguar are a part of inheritance hierarchy and as mentioned earlier, we require subtype/supertype relation between parameterized type like Garage[Lamborghini] (Garage of Lamborghini) is a subtype of Garage[Car](Garage of Car). For achieving this, the variance has come into the picture.

In Scala, the variance is divided into three parts:

  • Non-Variace (In-Variance)

  • Co-Variance

  • Contra-Variance

Before moving to the variance, we need to remember secret keys, which are:

  • Inheritance

  • Polymorphism

  • Liskov Substitution Principle(LSP):

    If class B is a Subclass of A, then every action we performing on A type, should also able to do with type B

    Or

    If we could be able to place B on all the places where the action performed by A with success, we can say that B is a Subclass of A

  • Be The Compiler

Diagram: 10.1
Copy from Head First Book Series
chapter 6th