Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to provide a default typeclass for generic types in Scala?

In Scala, if you create a typeclass, say the algebraic structure Monoid[T], you can provide many default typeclass implementations for different types that are monoids.

Suppose a monoid is defined as:

trait Monoid[T] {
  def op(x: T, y: T): T
  def id: T
}

Since Strings under the concatenation operation form a monoid, we can provide a default monoid for Strings like this:

implicit object StringMonoid extends Monoid[String] {
  override def op(a: String, b: String): String = a + b
  override def id: String = ""
}

This is rather easy, since String is not a generic type.

What I am asking for is how to provide a default monoid for Seq[T]s, in which the type parameter prevents me from creating an implicit object like I did above.

I could do:

class SeqMonoid[T] extends Monoid[Seq[T]] {
  override def op(a: Seq[T], b: Seq[T]): Seq[T] = a ++ b
  override def id: Seq[T] = Nil
}
implicit object intSeqMonoid extends SeqMonoid[Int]
implicit object doubleSeqMonoid extends SeqMonoid[Double]
implicit object stringSeqMonoid extends SeqMonoid[String]
...

But this approach doesn't utilize the beauty of generic types.

So, in general, my question is: Is there any way in Scala I can provide typeclass implementations for generic types?

like image 810
Yuhuan Jiang Avatar asked Jun 06 '15 07:06

Yuhuan Jiang


1 Answers

You can provide an implicit function with the required type:

implicit def SeqMonoid[T]: Monoid[Seq[T]] = new Monoid[Seq[T]] {
  override def op(a: Seq[T], b: Seq[T]): Seq[T] = a ++ b
  override def id: Seq[T] = Nil
}
like image 130
Kolmar Avatar answered Oct 05 '22 23:10

Kolmar