Dotty Documentation


Implementing Typeclasses

Edit this page on GitHub

Implied instance definitions, extension methods and context bounds allow a concise and natural expression of typeclasses. Typeclasses are just traits with canonical implementations defined by implied instance definitions. Here are some examples of standard typeclasses:

Semigroups and monoids:

trait SemiGroup[T] {
  def (x: T) combine (y: T): T
trait Monoid[T] extends SemiGroup[T] {
  def unit: T
object Monoid {
  def apply[T] = infer[Monoid[T]]

implied for Monoid[String] {
  def (x: String) combine (y: String): String = x.concat(y)
  def unit: String = ""

implied for Monoid[Int] {
  def (x: Int) combine (y: Int): Int = x + y
  def unit: String = 0

def sum[T: Monoid](xs: List[T]): T =

Functors and monads:

trait Functor[F[_]] {
  def (x: F[A]) map [A, B] (f: A => B): F[B]

trait Monad[F[_]] extends Functor[F] {
  def (x: F[A]) flatMap [A, B] (f: A => F[B]): F[B]
  def (x: F[A]) map [A, B] (f: A => B) = x.flatMap(f `andThen` pure)

  def pure[A](x: A): F[A]

implied ListMonad for Monad[List] {
  def (xs: List[A]) flatMap [A, B] (f: A => List[B]): List[B] =
  def pure[A](x: A): List[A] =

implied ReaderMonad[Ctx] for Monad[[X] => Ctx => X] {
  def (r: Ctx => A) flatMap [A, B] (f: A => Ctx => B): Ctx => B =
    ctx => f(r(ctx))(ctx)
  def pure[A](x: A): Ctx => A =
    ctx => x