WTF is a Type Class?

Edward Huang
Jan 7, 2020 · 3 min read
Originally published at https://edward-huang.com

I have a hard time understanding about type class a couple of weeks back while reading about Scala with Cats.

After countless research on the internet and other tutorial explaining Type Classes, I also decided to share my take and the way I look at them.

By knowing that the author of Cats Library used this technique to implement a lot of the functionality, I think it is handy as it was a widely used technique in designing the FP application.

This technique does not only limited to FP, but OOP can also use this technique to create a more modular system.

Type class is an interface that defines some behavior.

It is a way to create any behavior from an existing class without modifying anything on that source code. Instead, it creates a type class to implement the new behavior.

Type class usually define in 3 things:

  1. Instances of Type class: Defining the type class that we care about (concrete with implicit).
  2. Interface objects or interface syntax

A simple example from Alvin Alexander blog: Let’s say you have these existing data types:

Assumed that one day you need to add new behavior to Dog because it can speak like humans, you want to add a new speak behavior, but without really changing the source code you already have, and also not changing the behavior for Cat and Bird

Create a Trait that has a generic parameter:

trait SpeakBehavior[A] {
def speak(a:A):Unit
}

Create the instances of the type class that you want to enhance.

object SpeakLikeHuman{
implicit val dogSpeakLikeHuman: SpeakBehavior[Dog] = new SpeakBehavior[Dog] {
def speak(a:Dog): Unit = {
println(s"I'm a Dog, my name is ${dog.name})
}
}
}

Create an API for the consumers(caller) of this type class

BehavesLikeHuman.speak(aDog) // interface object
aDog.speak // interface syntax (using implicit class)

Interface Object (more explicit):

object BehavesLikeHuman {
def speak[A](a:A)(implicit instance: SpeakLikeHuman[A]) = instance.speak(a)
}

To call this type class:

import SpeakLikeHuman._ // import all the implicits
val dog = Dog("Rover")
BehavesLikeHuman.speak(dog)

Interface Syntax (implicit):

object BehavesLikeHumanSyntax {
implicit class BehavesLikeHumanOps[A](a:A) {
def speak(implicit instance:SpeakLikeHuman[A]): Unit = {
instance.speak(a)
}
}
}

Calling this:

import SpeakLikeHuman._ // import the instances
import BehavesLikeHumanSyntax.BehavesLikeHumanOps

val dog = Dog("Rover")
dog.speak // because implicitly gets it from the implicit class BehavesLikeHumanOps

To me, calling Interface syntax is not as readable as calling Interface objects, especially when you are trying to read a large codebase.

Implicit in Scala can be a double-edged sword, and for someone who is not used to reading Scala code, it can be hard for the first time to read a large codebase with multiple implicit. However, if you are using interface syntax on your API, the caller can invoke a new behavior directly on the instance — it looks like you added a new behavior to the Dog instance without changing any of the source code.

3 Main Takeaways

  • There are 3 steps to create a Type Class — the Interface, the Type-class instance, and the API
  • Be aware of interface syntax, and implicit in Scala because sometimes it can be hard to debug if you used it too often in a large codebase.

Full Source Code on the example above is in here.

Like this Article?

Other Articles You May like

Javarevisited

Medium’s largest Java publication, followed by 10000+ programmers. Follow to join our community.

Edward Huang

Written by

Software Engineer. Sharing my notes, thoughts, and document my journey in technology, functional programming, and careers in tech | https://www.Edward-Huang.com

Javarevisited

A humble place to learn Java and Programming better.

Edward Huang

Written by

Software Engineer. Sharing my notes, thoughts, and document my journey in technology, functional programming, and careers in tech | https://www.Edward-Huang.com

Javarevisited

A humble place to learn Java and Programming better.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store