The Scala Type Class Chronicles - Part 1

The Scala Type Class Chronicles - Part 1

Table of contents

No heading

No headings in the article.

Let’s say we’re writing a function to check if two integers are equal. Pretty simple, right? We can just compare them with the == and return true or false. So far, so good.

object Equal {
    println(2 == 3) // prints false
}

But what if we want to compare two strings? Well, we can still use ==, since it works on strings as well.

NB: Scala == operator on two strings checks whether the contents of the two strings are the same, whereas Java == operator on two strings checks if both the string references point to the same object in memory. In Java if you want to compare the values of two strings you use equals() method.

object Equal {
    println(2 == 3) // prints false
    println("2" == "2") // prints true
}

But then, what if we want to compare two lists of integers? Now it’s not as straightforward. == on lists check if they contain the same elements in the same order, which is good, but what if we need different criteria? Maybe we want to check if two lists have the same set of unique elements, regardless or order?


case class Person(name: String, age: Int)

object Equal {
    println(2 == 3) // prints false
    println("2" == "2") // prints true
    println(List(2, 3, 4) == List(4, 2, 3))
}

Or here’s an even trickier scenario: what if we want to compare the lists of custom objects like Person instances? How do we decide if two Person instances are equal? By their name? By their age? Maybe a combination of both? And can we apply this comparison to lists of Persons as easily as we did with integers?


case class Person(name: String, age: Int)

object Equal {
    val developer: Person = Person("Abhijit", 55)
    val anotherDeveloper: person = Person("Abhijit", 56)
    val tester: Person = Person("Ramesh", 56)

    println(2 == 3) // prints false
    println("2" == "2") // prints true
    println(List(2, 3, 4) == List(4, 2, 3)) // I want it returns true
    println(developer == tester) // want false
    println(developer == anotherDeveloper) // want true by name match
    println(developer == anotherDeveloper) // want false by name and age both match
}

This is where the concept of a type class comes to the rescue. By creating an Equal type class, we can define a standard way to compare values based on their type, without relying on Scala’s default ==. For each type—whether it’s an Int, a String, a List[Int], or even a custom type like Person—we can define exactly what it means for two instances to be “equal.” And we can even switch out this definition depending on our needs, without altering the original types.

With an Equality type class, we’re setting up a powerful, flexible way to define equality that’s reusable across all sorts of types—whether they’re basic types or more complex structures. This approach lets us write cleaner, more consistent code that adapts to different comparison needs. Let’s dive into how we can create this in Scala!

Did you find this article valuable?

Support Abhijit Dutta's blog by becoming a sponsor. Any amount is appreciated!