19.7. Selectively Adding New Behavior to a Closed Model

Problem

You have a closed model, and want to add new behavior to certain types within that model, while potentially excluding that behavior from being added to other types.

Solution

Implement your solution as a type class.

To demonstrate the problem and solution, when I first came to Scala, I thought it would be easy to write a single add method that would add any two numeric parameters, regardless of whether they were an Int, Double, Float, or other numeric value. Unfortunately I couldn’t get this to work—until I learned about type classes.

Because a Numeric type class already exists in the Scala library, it turns out that you can create an add method that accepts different numeric types like this:

def add[A](x: A, y: A)(implicit numeric: Numeric[A]): A = numeric.plus(x, y)

Once defined, this method can be used with different numeric types like this:

println(add(1, 1))
println(add(1.0, 1.5))
println(add(1, 1.5F))

The add method works because of some magic in the scala.math.Numeric trait. To see how this magic works, create your own type class.

Creating a type class

The process of creating a type class is a little complicated, but there is a formula:

  • Usually you start with a need, such as having a closed model to which you want to add new behavior.

  • To add the new behavior, you define a type class. The typical approach is to create a base trait, and then write specific implementations of that trait using implicit objects.

  • Back in your main ...

Get Scala Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.