Type Classes 103: The Cats Library

As a final example of how to use type classes in Scala, I’ll show how to repeat the example from the previous lesson using the open source “Cats” FP library for Scala. With the examples you’ve seen already, this will be a quick process.

Source code

Step 1 is to clone my source code for this lesson, which is available at this URL:

The first important thing to notice in this code is that I include the Cats library in the project with this line in the build.sbt file:

libraryDependencies ++= Seq(
    "org.typelevel" %% "cats-core" % "1.0.0-MF"
)

The Pizza class

In the source code, the Pizza case class is defined as usual:

case class Pizza (
    crustSize: CrustSize,
    crustType: CrustType,
    toppings: Seq[Topping]
)

Using Cats

In this lesson I’m going to use the Cats Show type class. Show is similar to the ToString type class I used in the previous lesson in that it provides a way to add a “to string” method to an existing class.

The first thing I do in my driver class is import everything I need from the Cats library:

import cats.Show           //the type class
import cats.syntax.show._  //the interface syntax

As the comments show, this imports the Cats Show type class and its interface syntax.

Next, this is how you create an implicit instance of the Show type class, which I name pizzaShow:

implicit val pizzaShow = Show.show[Pizza] { p =>
    s"""|Pizza(${p.crustSize}, ${p.crustType}),
        |      toppings = ${p.toppings}""".stripMargin
}

While that code is slightly different from what I showed in the previous lessons, I hope you can see the similarity between my approach and the Cats approach.

To use this implicit instance, all I have to do is create a Pizza:

val pizza = Pizza(
    LargeCrustSize,
    ThinCrustType,
    Seq(Cheese, Pepperoni, Sausage)
)

and then print it using the show method that’s now available to it, thanks to the pizzaShow instance:

println(pizza.show)

This results in the same output as in the previous lessons:

Pizza(LargeCrustSize, ThinCrustType),
      toppings = List(Cheese, Pepperoni, Sausage)

More about Cats and Show

If you’re serious about working with Scala/FP, I encourage you to get a copy of Advanced Scala with Cats. You can download the PDF for free, or donate any amount you want for the book. (The current suggested donation is $10, and it’s well worth that price if you want to use the Cats project.)

To see more about how Show works, start an SBT session from the root directory of the project for this lesson:

$ sbt

Then, inside of SBT, start a REPL session like this:

> console

After a few moments you’ll be in a Scala REPL session, with the additional benefit that the Cats library is available to you (thanks to this nice feature of SBT).

Now you can import the Show type class and its syntax, as before:

import cats.Show
import cats.syntax.show._

Then you can import a few pre-built instances Cats provides for you, including these for the Int and List types:

import cats.instances.int._
import cats.instances.list._

Once you’ve done that, you can call the show method on those built-in Scala types:

scala> 123.show            //Int
res0: String = 123

scala> List(1,2,3).show    //List
res1: String = List(1, 2, 3)

The Show library has instances for many more built-in Scala types. While this only shows the tip of the iceberg, I hope you can see the power of the approach.

Key points

The key points of this lesson are:

  • The Cats library has type classes like Show available, so you don’t always have to write your own
  • Even though the people who wrote Cats have never seen the Pizza class, it was easy to use Pizza and Show together because of the power of the type class approach
  • I also wanted to give you an idea of how to get started using Cats

See also

In this lesson I showed how to start a REPL session inside of SBT using the console command. You can also use the consoleQuick command to start a REPL session faster. I describe the two approaches here:

The two best Cats resources I know are here: