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 String
s under the concatenation operation form a monoid, we can provide a default monoid for String
s 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?
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With