Scala Language Type Classes Simple Type Class


Example

A type class is simply a trait with one or more type parameters:

trait Show[A] {
  def show(a: A): String
}

Instead of extending a type class, an implicit instance of the type class is provided for each supported type. Placing these implementations in the companion object of the type class allows implicit resolution to work without any special imports:

object Show {
  implicit val intShow: Show[Int] = new Show {
    def show(x: Int): String = x.toString
  }

  implicit val dateShow: Show[java.util.Date] = new Show {
    def show(x: java.util.Date): String = x.getTime.toString
  }

  // ..etc
}

If you want to guarantee that a generic parameter passed to a function has an instance of a type class, use implicit parameters:

def log[A](a: A)(implicit showInstance: Show[A]): Unit = {
  println(showInstance.show(a))
}

You can also use a context bound:

def log[A: Show](a: A): Unit = {
  println(implicitly[Show[A]].show(a))
}

Call the above log method like any other method. It will fail to compile if an implicit Show[A] implementation can't be found for the A you pass to log

log(10) // prints: "10"
log(new java.util.Date(1469491668401L) // prints: "1469491668401"
log(List(1,2,3)) // fails to compile with
                 // could not find implicit value for evidence parameter of type Show[List[Int]]

This example implements the Show type class. This is a common type class used to convert arbitrary instances of arbitrary types into Strings. Even though every object has a toString method, it's not always clear whether or not toString is defined in a useful way. With use of the Show type class, you can guarantee that anything passed to log has a well-defined conversion to String.