I was trying to implement SemiGroup in a generic manner for most of the scala types including collections. But when it comes to collection, I was stuck to implement the implicit SemiGroupImplicitTypes for collections.
For example: If I want to implement a SemiGroup[List[T]], It expects another param for the type of elements in List, I don't want to implement SemiGroup[List[Int]], SemiGroup[List[Double]] separately, want a single implementation for implicit, which will implement it for all types of List.
trait Semigroup[T] extends Any { def combine(a: T, b: T): T } object SemiGroup { def apply[T](a: T, b: T)(implicit ev: Semigroup[T]): T = ev.combine(a,b) } class SemiGroupList[T] extends Semigroup[List[T]] { override def combine(a: List[T], b: List[T]): List[T] = a ++ b } class SemiGroupSeq[T] extends Semigroup[Seq[T]] { override def combine(a: Seq[T], b: Seq[T]): Seq[T] = a ++ b } class SemiGroupMap[U, V] extends Semigroup[Map[U,V]] { override def combine(a: Map[U, V], b: Map[U, V]): Map[U, V] = a ++ b } class SemiGroupNumber[@specialized (Int, Double, Float, Long) T](implicit numeric: Numeric[T]) extends Semigroup[T] { override def combine(a: T, b: T): T = numeric.plus(a, b) } object SemiGroupImplicitTypes { implicit object IntSemiGroup extends SemiGroupNumber[Int] implicit object LongSemiGroup extends SemiGroupNumber[Long] implicit object DoubleSemiGroup extends SemiGroupNumber[Double] implicit object FloatSemiGroup extends SemiGroupNumber[Float] } import SemiGroupImplicitTypes._ SemiGroup[Long](1,2)
Semigroupis by now more-or-less semi-standardized: Semigroup.scala.