What are Type Classes
A type class is an interface that defines some behavior. Simply put, it is a programming technique that we often use to add new behaviors to existing user-defined data types without altering the source code.
Need for Type Class
While working on projects we often feel the need to add new behaviors to our user-defined types. A naive way to do it is to directly alter the source code.
Type class is a programming technique that allows us to add new behaviors to closed data types without using inheritance and without having access to the original source code of those types.
Problem Statement
We have an Employee case class.
sealed trait Person
case class Employee(name: String, experience: Int) extends Person
Now we will add a method promote to the employee object that simply prints if the employee is eligible to be promoted or not using his/her experience.
def promote(args...): Unit = {
/* Logic to determine whther the employee can be promted based on years of experience */
What we want is to be able to call this method like it belongs to the Employee class:
val emp = Employee("Prakhar")
emp.promote
3 Steps to create Type Classes in Scala
The process involves the creation of the following components:
- A trait with at least one generic type which will be the Type class
- An instance of the type class for the specific type that we want to extend
- Extension methods for the new functionality
Step 1: Creating the type class
The first step involves the creation of a generic trait with the behavior that we want to add to the Employee class
trait ExperiencedPerson[T] {
def promote(person: T): Unit
}
Step 2: Creating instance of the type class
Next, we make an instance and provide it with the behavior that we want to add to the Employee class
object ExperiencedPersonInstance {
implicit val experiencedEmployee: ExperiencedPerson[Employee] = new ExperiencedPerson[Employee] {
override def promote(employee: Employee): Unit = {
if(employee.experience > 3) println("I am experienced enough to be promoted.")
else println("I do not have enough experience to be promoted.")
}
}
}
Step 3: Creating the extension method
We write a method that will expose our newly created functionality and the goal is to access the methods directly from the instances of the Employee class.
To achieve this we make use of the Implicit classes.
object ExperiencedPerson {
import ExperiencedPersonInstance.experiencedEmployee
implicit class Promote[T](person: T) {
def promote(implicit experiencedPerson: ExperiencedPerson[T]): Unit = {
experiencedPerson.promote(person)
}
}
}
Main Class
In the code written above we see how to add a new method for the Employee class.
Next, we see how we can access the method as if it belongs to the Employee class
object Main extends App {
import ExperiencedPersonInstance.experiencedEmployee
import ExperiencedPerson._
val emp = Employee("Prakhar", 5)
emp.promote
}
Output
Here, the employee has experience of more than 3 years and so he is eligible to be promoted.

Conclusion
So in this blog, we create a type class in Scala and learn how to use them to extend the functionality of our Employee class.
We can now create more extensions in a similar way and add new behaviors without tinkering with the source code.