How to provide a standard model for generic types in Scala?

In Scala, if you create a type class, say, the Monoid[T] algebraic structure, you can provide many default implementations for types 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 forms a monoid during the concatenation operation, we can provide the default monoid for String as follows:

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

This is pretty easy since String not a generic type.

What I am asking is how to provide a default monoid for Seq[T] s , in which the type parameter prevents me from creating an implicit object, as 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 does not use the beauty of generic types.

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

+6
source share
2 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 } 
+7
source

Change without repeating Seq[T] :

 object Monoid { implicit def seqMonoid[T]:Monoid[Seq[T]] = { type S = Seq[T] new Monoid[S] { def op(x: S, y: S) = x ++ y def id = Nil } } } 
0
source

Source: https://habr.com/ru/post/988612/


All Articles