Dotty Documentation


Implementing Typeclasses

Edit this page on GitHub

Given instances, extension methods and context bounds allow a concise and natural expression of typeclasses. Typeclasses are just traits with canonical implementations defined by given instances. 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] given Monoid[T] = the[Monoid[T]]

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

given as Monoid[Int] {
  def (x: Int) combine (y: Int): Int = x + y
  def unit: Int = 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]

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

given ReaderMonad[Ctx] as 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