Skip to content

Commit

Permalink
feat: Add monoid for Positive0/Negative0
Browse files Browse the repository at this point in the history
  • Loading branch information
Iltotore committed Oct 10, 2024
1 parent ebfa7ca commit 4efa76c
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
36 changes: 34 additions & 2 deletions cats/src/io/github/iltotore/iron/instances.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.github.iltotore.iron

import _root_.cats.kernel.{CommutativeSemigroup, Hash, LowerBounded, PartialOrder, UpperBounded}
import _root_.cats.kernel.{CommutativeMonoid, CommutativeSemigroup, Hash, LowerBounded, PartialOrder, UpperBounded}
import _root_.cats.{Eq, Monoid, Order, Show, Traverse}
import io.github.iltotore.iron.constraint.numeric.*
import scala.util.NotGiven
import _root_.cats.Functor
import algebra.instances.all.*
import algebra.ring.AdditiveCommutativeSemigroup
import algebra.ring.{AdditiveCommutativeMonoid, AdditiveCommutativeSemigroup}

/**
* Represent all Cats' typeclass instances for Iron.
Expand Down Expand Up @@ -46,6 +46,23 @@ private[iron] trait IronCatsInstances extends IronCatsLowPriority, RefinedTypeOp
given negLongCommutativeSemigroup: CommutativeSemigroup[Long :| Negative] = commutativeSemigroup[Long, Negative]
given negFloatCommutativeSemigroup: CommutativeSemigroup[Float :| Negative] = commutativeSemigroup[Float, Negative]
given negDoubleCommutativeSemigroup: CommutativeSemigroup[Double :| Negative] = commutativeSemigroup[Double, Negative]

private def commutativeMonoid[A, C](using inner: CommutativeMonoid[A], bounds: Bounds[A, C]): CommutativeMonoid[A :| C] =
new CommutativeMonoid[A :| C]:

override def empty: A :| C = inner.empty.assume[C]

override def combine(a: A :| C, b: A :| C): A :| C = bounds.shift(inner.combine(a, b))

given posIntCommutativeMonoid: CommutativeMonoid[Int :| Positive0] = commutativeMonoid[Int, Positive0]
given posLongCommutativeMonoid: CommutativeMonoid[Long :| Positive0] = commutativeMonoid[Long, Positive0]
given posFloatCommutativeMonoid: CommutativeMonoid[Float :| Positive0] = commutativeMonoid[Float, Positive0]
given posDoubleCommutativeMonoid: CommutativeMonoid[Double :| Positive0] = commutativeMonoid[Double, Positive0]

given negIntCommutativeMonoid: CommutativeMonoid[Int :| Negative0] = commutativeMonoid[Int, Negative0]
given negLongCommutativeMonoid: CommutativeMonoid[Long :| Negative0] = commutativeMonoid[Long, Negative0]
given negFloatCommutativeMonoid: CommutativeMonoid[Float :| Negative0] = commutativeMonoid[Float, Negative0]
given negDoubleCommutativeMonoid: CommutativeMonoid[Double :| Negative0] = commutativeMonoid[Double, Negative0]

/**
* Cats' instances for Iron that need to have a lower priority to avoid ambiguous implicits.
Expand Down Expand Up @@ -81,4 +98,19 @@ private trait RefinedTypeOpsCatsLowPriority:
given negFloatAdditiveCommutativeSemigroup: AdditiveCommutativeSemigroup[Float :| Negative] = additiveCommutativeSemigroup[Float, Negative]
given negDoubleAdditiveCommutativeSemigroup: AdditiveCommutativeSemigroup[Double :| Negative] = additiveCommutativeSemigroup[Double, Negative]

private def additiveCommutativeMonoid[A, C](using inner: AdditiveCommutativeMonoid[A], bounds: Bounds[A, C]): AdditiveCommutativeMonoid[A :| C] = new:

override def zero: A :| C = inner.zero.assume[C]
override def plus(x: A :| C, y: A :| C): A :| C = bounds.shift(inner.plus(x, y))

given posIntAdditiveCommutativeMonoid: AdditiveCommutativeMonoid[Int :| Positive0] = additiveCommutativeMonoid[Int, Positive0]
given posLongAdditiveCommutativeMonoid: AdditiveCommutativeMonoid[Long :| Positive0] = additiveCommutativeMonoid[Long, Positive0]
given posFloatAdditiveCommutativeMonoid: AdditiveCommutativeMonoid[Float :| Positive0] = additiveCommutativeMonoid[Float, Positive0]
given posDoubleAdditiveCommutativeMonoid: AdditiveCommutativeMonoid[Double :| Positive0] = additiveCommutativeMonoid[Double, Positive0]

given negIntAdditiveCommutativeMonoid: AdditiveCommutativeMonoid[Int :| Negative0] = additiveCommutativeMonoid[Int, Negative0]
given negLongAdditiveCommutativeMonoid: AdditiveCommutativeMonoid[Long :| Negative0] = additiveCommutativeMonoid[Long, Negative0]
given negFloatAdditiveCommutativeMonoid: AdditiveCommutativeMonoid[Float :| Negative0] = additiveCommutativeMonoid[Float, Negative0]
given negDoubleAdditiveCommutativeMonoid: AdditiveCommutativeMonoid[Double :| Negative0] = additiveCommutativeMonoid[Double, Negative0]


36 changes: 35 additions & 1 deletion cats/test/src/io/github/iltotore/iron/CatsSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import _root_.cats.data.NonEmptyList
import _root_.cats.data.Validated.{Invalid, Valid}

import scala.runtime.stdLibPatches.Predef.assert
import algebra.ring.AdditiveCommutativeSemigroup
import algebra.ring.{AdditiveCommutativeMonoid, AdditiveCommutativeSemigroup}

object CatsSuite extends TestSuite:

Expand Down Expand Up @@ -86,6 +86,23 @@ object CatsSuite extends TestSuite:
test("pos") - assert(CommutativeSemigroup[Double :| Positive].combine(1, 5) == 6)
test("neg") - assert(CommutativeSemigroup[Double :| Negative].combine(-1, -5) == -6)

test("commutativeMonoid"):
test("int"):
test("pos") - assert(CommutativeMonoid[Int :| Positive0].combine(1, 5) == 6)
test("neg") - assert(CommutativeMonoid[Int :| Negative0].combine(-1, -5) == -6)

test("long"):
test("pos") - assert(CommutativeMonoid[Long :| Positive0].combine(1, 5) == 6)
test("neg") - assert(CommutativeMonoid[Long :| Negative0].combine(-1, -5) == -6)

test("float"):
test("pos") - assert(CommutativeMonoid[Float :| Positive0].combine(1, 5) == 6)
test("neg") - assert(CommutativeMonoid[Float :| Negative0].combine(-1, -5) == -6)

test("double"):
test("pos") - assert(CommutativeMonoid[Double :| Positive0].combine(1, 5) == 6)
test("neg") - assert(CommutativeMonoid[Double :| Negative0].combine(-1, -5) == -6)

test("additiveCommutativeSemigroup"):
test("int"):
test("pos") - assert(AdditiveCommutativeSemigroup[Int :| Positive].plus(1, 5) == 6)
Expand All @@ -102,6 +119,23 @@ object CatsSuite extends TestSuite:
test("double"):
test("pos") - assert(AdditiveCommutativeSemigroup[Double :| Positive].plus(1, 5) == 6)
test("neg") - assert(AdditiveCommutativeSemigroup[Double :| Negative].plus(-1, -5) == -6)

test("additiveCommutativeMonoid"):
test("int"):
test("pos") - assert(AdditiveCommutativeMonoid[Int :| Positive0].plus(1, 5) == 6)
test("neg") - assert(AdditiveCommutativeMonoid[Int :| Negative0].plus(-1, -5) == -6)

test("long"):
test("pos") - assert(AdditiveCommutativeMonoid[Long :| Positive0].plus(1, 5) == 6)
test("neg") - assert(AdditiveCommutativeMonoid[Long :| Negative0].plus(-1, -5) == -6)

test("float"):
test("pos") - assert(AdditiveCommutativeMonoid[Float :| Positive0].plus(1, 5) == 6)
test("neg") - assert(AdditiveCommutativeMonoid[Float :| Negative0].plus(-1, -5) == -6)

test("double"):
test("pos") - assert(AdditiveCommutativeMonoid[Double :| Positive0].plus(1, 5) == 6)
test("neg") - assert(AdditiveCommutativeMonoid[Double :| Negative0].plus(-1, -5) == -6)
}

test("eitherNec"):
Expand Down

0 comments on commit 4efa76c

Please sign in to comment.