Scala Language Type Classes Extending a Type Class


Example

This example discusses extending the below type class.

trait Show[A] {
  def show: String
}

To make a class you control (and is written in Scala) extend the type class, add an implicit to its companion object. Let us show how we can get the Person class from this example to extend Show:

class Person(val fullName: String) {    
  def this(firstName: String, lastName: String) = this(s"$firstName $lastName")
}

We can make this class extend Show by adding an implicit to Person's companion object:

object Person {
  implicit val personShow: Show[Person] = new Show {
    def show(p: Person): String = s"Person(${p.fullname})"
  }
}

A companion object must be in the same file as the class, so you need both class Person and object Person in the same file.

To make a class you do not control, or is not written in Scala, extend the type class, add an implicit to the companion object of the type class, as shown in the Simple Type Class example.

If you control neither the class nor the type class, create an implicit as above anywhere, and import it. Using the log method on the Simple Type Class example:

object MyShow {
  implicit val personShow: Show[Person] = new Show {
    def show(p: Person): String = s"Person(${p.fullname})"
  }
}

def logPeople(persons: Person*): Unit = {
  import MyShow.personShow
  persons foreach { p => log(p) }
}