Reputation: 13
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
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