Skip to content

Commit

Permalink
Use helper constructor for (Commutative)Semigroup instances
Browse files Browse the repository at this point in the history
  • Loading branch information
joroKr21 committed Aug 12, 2022
1 parent 63d8d96 commit b5207a7
Show file tree
Hide file tree
Showing 18 changed files with 41 additions and 94 deletions.
9 changes: 3 additions & 6 deletions algebra-core/src/main/scala/algebra/ring/Multiplicative.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ import scala.annotation.{nowarn, tailrec}

trait MultiplicativeSemigroup[@sp(Int, Long, Float, Double) A] extends Any with Serializable {
def multiplicative: Semigroup[A] =
new Semigroup[A] {
def combine(x: A, y: A): A = times(x, y)
}
Semigroup.instance(times)

def times(x: A, y: A): A

Expand Down Expand Up @@ -58,9 +56,8 @@ trait MultiplicativeSemigroup[@sp(Int, Long, Float, Double) A] extends Any with
}

trait MultiplicativeCommutativeSemigroup[@sp(Int, Long, Float, Double) A] extends Any with MultiplicativeSemigroup[A] {
override def multiplicative: CommutativeSemigroup[A] = new CommutativeSemigroup[A] {
def combine(x: A, y: A): A = times(x, y)
}
override def multiplicative: CommutativeSemigroup[A] =
CommutativeSemigroup.instance(times)
}

trait MultiplicativeMonoid[@sp(Int, Long, Float, Double) A] extends Any with MultiplicativeSemigroup[A] {
Expand Down
6 changes: 0 additions & 6 deletions algebra-core/src/test/scala/algebra/Instances.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ package algebra

object Instances {

def t2HasSemigroup[A, B](implicit eva: Semigroup[A], evb: Semigroup[B]) =
new Semigroup[(A, B)] {
def combine(x: (A, B), y: (A, B)): (A, B) =
(eva.combine(x._1, y._1), evb.combine(x._2, y._2))
}

val stringHasMonoid =
new Monoid[String] {
def empty: String = ""
Expand Down
4 changes: 1 addition & 3 deletions core/src/main/scala/cats/Align.scala
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,7 @@ trait Align[F[_]] extends Serializable {

object Align extends ScalaVersionSpecificAlignInstances {
def semigroup[F[_], A](implicit F: Align[F], A: Semigroup[A]): Semigroup[F[A]] =
new Semigroup[F[A]] {
def combine(x: F[A], y: F[A]): F[A] = Align[F].alignCombine(x, y)
}
Semigroup.instance(F.alignCombine[A])

implicit def catsAlignForList: Align[List] = cats.instances.list.catsStdInstancesForList
implicit def catsAlignForOption: Align[Option] = cats.instances.option.catsStdInstancesForOption
Expand Down
6 changes: 1 addition & 5 deletions core/src/main/scala/cats/CommutativeApply.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@ trait CommutativeApply[F[_]] extends Apply[F]

object CommutativeApply {
def commutativeSemigroupFor[F[_]: CommutativeApply, A: CommutativeSemigroup]: CommutativeSemigroup[F[A]] =
new CommutativeSemigroup[F[A]] {
override def combine(x: F[A], y: F[A]): F[A] =
CommutativeApply[F]
.map2(x, y)(CommutativeSemigroup[A].combine)
}
CommutativeSemigroup.instance(CommutativeApply[F].map2(_, _)(CommutativeSemigroup[A].combine))

/**
* Summon an instance of [[CommutativeApply]] for `F`.
Expand Down
4 changes: 1 addition & 3 deletions core/src/main/scala/cats/SemigroupK.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,7 @@ trait SemigroupK[F[_]] extends Serializable { self =>
* }}}
*/
def algebra[A]: Semigroup[F[A]] =
new Semigroup[F[A]] {
def combine(x: F[A], y: F[A]): F[A] = self.combineK(x, y)
}
Semigroup.instance(combineK)

/**
* "Compose" with a `G[_]` type to form a `SemigroupK` for `λ[α => F[G[α]]]`.
Expand Down
4 changes: 1 addition & 3 deletions core/src/main/scala/cats/arrow/Compose.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ trait Compose[F[_, _]] extends Serializable { self =>
}

def algebra[A]: Semigroup[F[A, A]] =
new Semigroup[F[A, A]] {
def combine(f1: F[A, A], f2: F[A, A]): F[A, A] = self.compose(f1, f2)
}
Semigroup.instance(compose)
}

object Compose {
Expand Down
4 changes: 1 addition & 3 deletions core/src/main/scala/cats/data/Const.scala
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,7 @@ sealed abstract private[data] class ConstInstances1 extends ConstInstances2 {
sealed abstract private[data] class ConstInstances2 extends ConstInstances3 {

implicit def catsDataSemigroupForConst[A: Semigroup, B]: Semigroup[Const[A, B]] =
new Semigroup[Const[A, B]] {
def combine(x: Const[A, B], y: Const[A, B]): Const[A, B] = x.combine(y)
}
Semigroup.instance(_ combine _)

implicit def catsDataPartialOrderForConst[A: PartialOrder, B]: PartialOrder[Const[A, B]] =
PartialOrder.from(_ partialCompare _)
Expand Down
4 changes: 1 addition & 3 deletions core/src/main/scala/cats/data/Ior.scala
Original file line number Diff line number Diff line change
Expand Up @@ -864,9 +864,7 @@ sealed abstract private[data] class IorInstances extends IorInstances0 {
Show.show(_.show)

implicit def catsDataSemigroupForIor[A: Semigroup, B: Semigroup]: Semigroup[Ior[A, B]] =
new Semigroup[Ior[A, B]] {
def combine(x: Ior[A, B], y: Ior[A, B]) = x.combine(y)
}
Semigroup.instance(_ combine _)

implicit def catsDataMonadErrorForIor[A: Semigroup]: MonadError[Ior[A, *], A] =
new MonadError[Ior[A, *], A] {
Expand Down
7 changes: 2 additions & 5 deletions core/src/main/scala/cats/data/NonEmptyMapImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -374,11 +374,8 @@ sealed abstract private[data] class NonEmptyMapInstances extends NonEmptyMapInst
}

implicit def catsDataSemigroupForNonEmptyMap[K, A: Semigroup]: Semigroup[NonEmptyMap[K, A]] =
new Semigroup[NonEmptyMap[K, A]] {
def combine(x: NonEmptyMap[K, A], y: NonEmptyMap[K, A]): NonEmptyMap[K, A] =
NonEmptyMap.fromMapUnsafe(
Semigroup[SortedMap[K, A]].combine(x.toSortedMap, y.toSortedMap)
)
Semigroup.instance { (x, y) =>
NonEmptyMap.fromMapUnsafe(Semigroup[SortedMap[K, A]].combine(x.toSortedMap, y.toSortedMap))
}
}

Expand Down
4 changes: 1 addition & 3 deletions core/src/main/scala/cats/data/Validated.scala
Original file line number Diff line number Diff line change
Expand Up @@ -979,9 +979,7 @@ sealed abstract private[data] class ValidatedInstances1 extends ValidatedInstanc
A: Semigroup[A],
B: Semigroup[B]
): Semigroup[Validated[A, B]] =
new Semigroup[Validated[A, B]] {
def combine(x: Validated[A, B], y: Validated[A, B]): Validated[A, B] = x.combine(y)
}
Semigroup.instance(_ combine _)

implicit def catsDataCommutativeApplicativeForValidated[E: CommutativeSemigroup]
: CommutativeApplicative[Validated[E, *]] =
Expand Down
16 changes: 4 additions & 12 deletions core/src/main/scala/cats/instances/invariant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,21 @@ trait InvariantMonoidalInstances {

implicit val catsInvariantMonoidalSemigroup: InvariantMonoidal[Semigroup] = new InvariantMonoidal[Semigroup] {
def product[A, B](fa: Semigroup[A], fb: Semigroup[B]): Semigroup[(A, B)] =
new Semigroup[(A, B)] {
def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2)
}
Semigroup.instance((x, y) => fa.combine(x._1, y._1) -> fb.combine(x._2, y._2))

def imap[A, B](fa: Semigroup[A])(f: A => B)(g: B => A): Semigroup[B] =
new Semigroup[B] {
def combine(x: B, y: B): B = f(fa.combine(g(x), g(y)))
}
Semigroup.instance((x, y) => f(fa.combine(g(x), g(y))))

def unit: Semigroup[Unit] = implicitly
}

implicit val catsInvariantMonoidalCommutativeSemigroup: InvariantMonoidal[CommutativeSemigroup] =
new InvariantMonoidal[CommutativeSemigroup] {
def product[A, B](fa: CommutativeSemigroup[A], fb: CommutativeSemigroup[B]): CommutativeSemigroup[(A, B)] =
new CommutativeSemigroup[(A, B)] {
def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2)
}
CommutativeSemigroup.instance((x, y) => fa.combine(x._1, y._1) -> fb.combine(x._2, y._2))

def imap[A, B](fa: CommutativeSemigroup[A])(f: A => B)(g: B => A): CommutativeSemigroup[B] =
new CommutativeSemigroup[B] {
def combine(x: B, y: B): B = f(fa.combine(g(x), g(y)))
}
CommutativeSemigroup.instance((x, y) => f(fa.combine(g(x), g(y))))

def unit: CommutativeSemigroup[Unit] = implicitly
}
Expand Down
10 changes: 3 additions & 7 deletions docs/typeclasses/invariantmonoidal.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,11 @@ To construct a `Semigroup` from a single value, we can define a trivial `Semigro
import cats.Semigroup

def unit: Semigroup[Unit] =
new Semigroup[Unit] {
def combine(x: Unit, y: Unit): Unit = ()
}
Semigroup.instance((_, _) => ())

def product[A, B](fa: Semigroup[A], fb: Semigroup[B]): Semigroup[(A, B)] =
new Semigroup[(A, B)] {
def combine(x: (A, B), y: (A, B)): (A, B) = (x, y) match {
case ((xa, xb), (ya, yb)) => fa.combine(xa, ya) -> fb.combine(xb, yb)
}
Semigroup.instances { case ((xa, xb), (ya, yb)) =>
fa.combine(xa, ya) -> fb.combine(xb, yb)
}
```

Expand Down
2 changes: 1 addition & 1 deletion docs/typeclasses/lawtesting.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ implicit def semigroupTree[A: Semigroup]: Semigroup[Tree[A]] = new Semigroup[Tre
case (Leaf, _) => Leaf
case (_, Leaf) => Leaf
case (Node(xp, xLeft, xRight), Node(yp, yLeft, yRight)) =>
Node(xp |+| yp, xLeft |+| yLeft, xRight |+| yRight)
Node(xp |+| yp, combine(xLeft, yLeft), combine(xRight, yRight))
}
}
```
Expand Down
4 changes: 1 addition & 3 deletions docs/typeclasses/monoid.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,7 @@ final case class NonEmptyList[A](head: A, tail: List[A]) {

object NonEmptyList {
implicit def nonEmptyListSemigroup[A]: Semigroup[NonEmptyList[A]] =
new Semigroup[NonEmptyList[A]] {
def combine(x: NonEmptyList[A], y: NonEmptyList[A]): NonEmptyList[A] = x ++ y
}
Semigroup.instance(_ ++ _)
}
```

Expand Down
5 changes: 2 additions & 3 deletions docs/typeclasses/semigroup.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ A common example of a semigroup is the type `Int` with the operation `+`.
```scala mdoc:reset:silent
import cats.Semigroup

implicit val intAdditionSemigroup: Semigroup[Int] = new Semigroup[Int] {
def combine(x: Int, y: Int): Int = x + y
}
implicit val intAdditionSemigroup: Semigroup[Int] =
Semigroup.instance(_ + _)

val x = 1
val y = 2
Expand Down
6 changes: 2 additions & 4 deletions kernel/src/main/scala/cats/kernel/CommutativeSemigroup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ object CommutativeSemigroup extends SemigroupFunctions[CommutativeSemigroup] {
/**
* Create a `CommutativeSemigroup` instance from the given function.
*/
@inline def instance[A](cmb: (A, A) => A): CommutativeSemigroup[A] =
new CommutativeSemigroup[A] {
override def combine(x: A, y: A): A = cmb(x, y)
}
@inline def instance[@sp(Int, Long, Float, Double) A](cmb: (A, A) => A): CommutativeSemigroup[A] =
cmb(_, _)
}
21 changes: 7 additions & 14 deletions kernel/src/main/scala/cats/kernel/Semigroup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

package cats.kernel

import cats.kernel.Semigroup.instance

import scala.annotation.tailrec
import scala.collection.immutable.{BitSet, Queue, Seq, SortedMap, SortedSet}
import scala.concurrent.{ExecutionContext, Future}
Expand Down Expand Up @@ -120,10 +122,7 @@ trait Semigroup[@sp(Int, Long, Float, Double) A] extends Any with Serializable {
* This name matches the term used in Foldable and Reducible and a similar Haskell function.
*/
def intercalate(middle: A): Semigroup[A] =
new Semigroup[A] {
def combine(a: A, b: A): A =
self.combine(a, self.combine(middle, b))
}
instance((a, b) => self.combine(a, self.combine(middle, b)))
}

abstract class SemigroupFunctions[S[T] <: Semigroup[T]] {
Expand Down Expand Up @@ -169,26 +168,20 @@ object Semigroup
/**
* Create a `Semigroup` instance from the given function.
*/
@inline def instance[A](cmb: (A, A) => A): Semigroup[A] =
new Semigroup[A] {
override def combine(x: A, y: A): A = cmb(x, y)
}
@inline def instance[@sp(Int, Long, Float, Double) A](cmb: (A, A) => A): Semigroup[A] =
cmb(_, _)

/**
* Create a `Semigroup` instance that always returns the lefthand side.
*/
@inline def first[A]: Semigroup[A] =
new Semigroup[A] {
override def combine(x: A, y: A): A = x
}
instance((x, _) => x)

/**
* Create a `Semigroup` instance that always returns the righthand side.
*/
@inline def last[A]: Semigroup[A] =
new Semigroup[A] {
override def combine(x: A, y: A): A = y
}
instance((_, y) => y)

This comment has been minimized.

Copy link
@KingNemzz

KingNemzz Oct 29, 2022

kernel/src/main/scala/cats/kernel/Semigroup.scala

This comment has been minimized.

Copy link
@KingNemzz
implicit def catsKernelBoundedSemilatticeForBitSet: BoundedSemilattice[BitSet] =
cats.kernel.instances.bitSet.catsKernelStdSemilatticeForBitSet
Expand Down
19 changes: 9 additions & 10 deletions kernel/src/main/scala/cats/kernel/instances/EitherInstances.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,15 @@ trait EitherInstances extends EitherInstances0 {
private[instances] trait EitherInstances0 extends EitherInstances1 {

implicit def catsDataSemigroupForEither[A, B](implicit B: Semigroup[B]): Semigroup[Either[A, B]] =
new Semigroup[Either[A, B]] {
def combine(x: Either[A, B], y: Either[A, B]): Either[A, B] =
x match {
case left @ Left(_) => left
case Right(xx) =>
y match {
case left @ Left(_) => left
case Right(yy) => Right(B.combine(xx, yy))
}
}
Semigroup.instance { (x, y) =>
x match {
case left @ Left(_) => left
case Right(xx) =>
y match {
case left @ Left(_) => left
case Right(yy) => Right(B.combine(xx, yy))
}
}
}

implicit def catsStdPartialOrderForEither[A, B](implicit
Expand Down

0 comments on commit b5207a7

Please sign in to comment.