Questions And Answers

More Tutorials

Scala Type Classes


Simple Type Class

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 = {

You can also use a context bound:

def log[A: Show](a: A): Unit = {

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

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.

Extending a Type Class

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) }


In this page (written and validated by ) you learned about Scala Type Classes . What's Next? If you are interested in completing Scala tutorial, your next topic will be learning about: Scala Type Inference.

Incorrect info or code snippet? We take very seriously the accuracy of the information provided on our website. We also make sure to test all snippets and examples provided for each section. If you find any incorrect information, please send us an email about the issue:

Share On:

Mockstacks was launched to help beginners learn programming languages; the site is optimized with no Ads as, Ads might slow down the performance. We also don't track any personal information; we also don't collect any kind of data unless the user provided us a corrected information. Almost all examples have been tested. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. By using, you agree to have read and accepted our terms of use, cookies and privacy policy.