Scala supports ad-hoc polymorphism via traits, context bounds, and implicits.
Start with a generic trait with a single type parameter:
trait Showable[S] {
def show(s: S): String
}
Using a context bound, pull in an implicit instance of the type class:
implicit class ShowableOps[S: Showable](s: S) {
def show: String =
[Showable[S]].show(s)
implicitly}
Write a concrete, implicit instance of the type class:
implicit object IntShowable extends Showable[Int] {
def show(s: Int): String =
s"The number ${s}"
}
Use it:
println(42.show) // prints "The number 42"