Merlijn van Ittersum
Merlijn van Ittersum

Reputation: 13

Type class API in Scala

This is a pattern I am considering to use in Scala to define a contract without limiting the type but still having a fluent API without all the verbose implicity[..].

The idea is to build a implicit class on top of a type class like so:

implicit class NumberLikeApi[N : NumberLike](n: N)
  def add(n2: N): N = implicitely[NumberLike[N]].add(n, n2)
}

Now with the right implicits in scope you can do:

val sum = n1.add(n2)

Instead of:

val sum = implicitly[NumberLike[N]].add(n1, n2)

My question: Is it somehow possible to automate / generate the implicit class part? It is basically a duplication of the type class.

I failed to find something in the language & standard library. Is there perhaps a macro in a library somewhere that can do this?

Upvotes: 1

Views: 132

Answers (1)

Gabriele Petronella
Gabriele Petronella

Reputation: 108091

The purpose of simulacrum should be exactly this.

From its README, you can write

import simulacrum._

@typeclass trait Semigroup[A] {
  @op("|+|") def append(x: A, y: A): A
}

and then use it like

// instance for Semigroup[Int] 
implicit val semigroupInt: Semigroup[Int] = new Semigroup[Int] {
  def append(x: Int, y: Int) = x + y
}

import Semigroup.ops._

1 |+| 2 // 3

Upvotes: 2

Related Questions