Skip to content

Commit

Permalink
Merge pull request #3 from kailuowang/LukaJCB-add-monoidal-to-monoid
Browse files Browse the repository at this point in the history
Luka jcb add monoidal to monoid
  • Loading branch information
LukaJCB authored Dec 18, 2017
2 parents 7880ada + 4b73af8 commit 30391e8
Show file tree
Hide file tree
Showing 15 changed files with 100 additions and 60 deletions.
10 changes: 0 additions & 10 deletions core/src/main/scala/cats/data/Const.scala
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,6 @@ private[data] sealed abstract class ConstInstances0 extends ConstInstances1 {
}

private[data] sealed abstract class ConstInstances1 {
implicit def catsConstInvariantMonoidal[C: Monoid]: InvariantMonoidal[Const[C, ?]] = new InvariantMonoidal[Const[C, ?]] {
def unit: Const[C, Unit] =
Const.empty

def imap[A, B](fa: Const[C, A])(f: A => B)(g: B => A): Const[C, B] =
fa.retag[B]

def product[A, B](fa: Const[C, A], fb: Const[C, B]): Const[C, (A, B)] =
fa.retag[(A, B)] combine fb.retag[(A, B)]
}

implicit def catsDataEqForConst[A: Eq, B]: Eq[Const[A, B]] = new Eq[Const[A, B]] {
def eqv(x: Const[A, B], y: Const[A, B]): Boolean =
Expand Down
4 changes: 0 additions & 4 deletions core/src/main/scala/cats/data/IndexedStateT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,6 @@ private[data] sealed abstract class IndexedStateTInstances extends IndexedStateT
implicit def catsDataAlternativeForIndexedStateT[F[_], S](implicit FM: Monad[F],
FA: Alternative[F]): Alternative[IndexedStateT[F, S, S, ?]] with Monad[IndexedStateT[F, S, S, ?]] =
new IndexedStateTAlternative[F, S] { implicit def F = FM; implicit def G = FA }

implicit def catsDataContravariantMonoidalForIndexedStateT[F[_], S](implicit FD: ContravariantMonoidal[F],
FA: Applicative[F]): ContravariantMonoidal[IndexedStateT[F, S, S, ?]] =
new IndexedStateTContravariantMonoidal[F, S] { implicit def F = FD; implicit def G = FA }
}

private[data] sealed abstract class IndexedStateTInstances1 extends IndexedStateTInstances2 {
Expand Down
7 changes: 5 additions & 2 deletions core/src/main/scala/cats/instances/partialOrder.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package cats
package instances
import cats.kernel.instances.unit._

trait PartialOrderInstances {
implicit val catsContravariantSemigroupalForPartialOrder: ContravariantSemigroupal[PartialOrder] =
new ContravariantSemigroupal[PartialOrder] {
implicit val catsContravariantMonoidalForPartialOrder: ContravariantMonoidal[PartialOrder] =
new ContravariantMonoidal[PartialOrder] {
/** Derive a `PartialOrder` for `B` given a `PartialOrder[A]` and a function `B => A`.
*
* Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping)
Expand All @@ -17,5 +18,7 @@ trait PartialOrderInstances {
if (z == 0.0) fb.partialCompare(x._2, y._2) else z
}
}

def unit: PartialOrder[Unit] = Order[Unit]
}
}
6 changes: 4 additions & 2 deletions core/src/main/scala/cats/instances/partialOrdering.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package cats
package instances

trait PartialOrderingInstances {
implicit val catsContravariantSemigroupalForPartialOrdering: ContravariantSemigroupal[PartialOrdering] =
new ContravariantSemigroupal[PartialOrdering] {
implicit val catsContravariantMonoidalForPartialOrdering: ContravariantMonoidal[PartialOrdering] =
new ContravariantMonoidal[PartialOrdering] {
/** Derive a `PartialOrdering` for `B` given a `PartialOrdering[A]` and a function `B => A`.
*
* Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping)
Expand All @@ -24,5 +24,7 @@ trait PartialOrderingInstances {
case option => option
}
}

def unit: PartialOrdering[Unit] = cats.instances.unit.catsKernelStdOrderForUnit.toOrdering
}
}
3 changes: 3 additions & 0 deletions kernel/src/main/scala/cats/kernel/Order.scala
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ abstract class OrderFunctions[O[T] <: Order[T]] extends PartialOrderFunctions[O]

def max[@sp A](x: A, y: A)(implicit ev: O[A]): A =
ev.max(x, y)

def comparison[@sp A](x: A, y: A)(implicit ev: O[A]): Comparison =
ev.comparison(x, y)
}

trait OrderToOrderingConversion {
Expand Down
8 changes: 4 additions & 4 deletions laws/src/main/scala/cats/laws/InvariantMonoidalLaws.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ trait InvariantMonoidalLaws[F[_]] extends InvariantSemigroupalLaws[F] {
import cats.syntax.semigroupal._
import cats.syntax.invariant._

def invariantMonoidalLeftIdentity[A, B](fa: F[A], b: B): IsEq[F[A]] =
F.point(b).product(fa).imap(_._2)(a => (b, a)) <-> fa
def invariantMonoidalLeftIdentity[A, B](fa: F[A]): IsEq[F[A]] =
F.unit.product(fa).imap(_._2)(a => ((), a)) <-> fa

def invariantMonoidalRightIdentity[A, B](fa: F[A], b: B): IsEq[F[A]] =
fa.product(F.point(b)).imap(_._1)(a => (a, b)) <-> fa
def invariantMonoidalRightIdentity[A, B](fa: F[A]): IsEq[F[A]] =
fa.product(F.unit).imap(_._1)(a => (a, ())) <-> fa

def invariantMonoidalAssociativity[A, B, C](fa: F[A], fb: F[B], fc: F[C]):
IsEq[F[(A, (B, C))]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ trait InvariantMonoidalTests[F[_]] extends InvariantSemigroupalTests[F] {
val parents = Seq(invariant[A, B, C], semigroupal[A, B, C])
val bases = Seq.empty
val props = Seq(
"invariant monoidal left identity" -> forAll((fa: F[A], b: B) => laws.invariantMonoidalLeftIdentity(fa, b)),
"invariant monoidal right identity" -> forAll((fa: F[A], b: B) => laws.invariantMonoidalRightIdentity(fa, b)),
"invariant monoidal left identity" -> forAll((fa: F[A]) => laws.invariantMonoidalLeftIdentity(fa)),
"invariant monoidal right identity" -> forAll((fa: F[A]) => laws.invariantMonoidalRightIdentity(fa)),
"invariant monoidal associativity" -> forAll((fa: F[A], fb: F[B], fc: F[C]) => laws.invariantMonoidalAssociativity(fa, fb, fc))
)
}
Expand Down
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC12")
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0")
addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.1")
addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.6")
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.0")
Expand Down
2 changes: 1 addition & 1 deletion project/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC11")
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0")
16 changes: 8 additions & 8 deletions scalafix/rules/src/main/scala/fix/Cats_v1_0_0.scala
Original file line number Diff line number Diff line change
Expand Up @@ -247,14 +247,14 @@ case class RenameApplyApConst(index: SemanticdbIndex)

override def fix(ctx: RuleCtx): Patch =
ctx.replaceSymbols(
"_root_.cats.Apply.forEffect." -> "apL",
"_root_.cats.Apply.followedBy." -> "apR",
"_root_.cats.Apply.Ops.forEffect." -> "apL",
"_root_.cats.Apply.Ops.followedBy." -> "apR",
"_root_.cats.NonEmptyParallel.parForEffect." -> "parApL",
"_root_.cats.NonEmptyParallel.parFollowedBy." -> "parApR",
"_root_.cats.FlatMap.forEffectEval." -> "apLEval",
"_root_.cats.FlatMap.followedByEval." -> "apREval",
"_root_.cats.Apply.forEffect." -> "productL",
"_root_.cats.Apply.followedBy." -> "productR",
"_root_.cats.Apply.Ops.forEffect." -> "productL",
"_root_.cats.Apply.Ops.followedBy." -> "productR",
"_root_.cats.NonEmptyParallel.parForEffect." -> "parProductL",
"_root_.cats.NonEmptyParallel.parFollowedBy." -> "parProductR",
"_root_.cats.FlatMap.forEffectEval." -> "productLEval",
"_root_.cats.FlatMap.followedByEval." -> "productREval",
)

}
Expand Down
22 changes: 8 additions & 14 deletions tests/src/test/scala/cats/tests/EqSuite.scala
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
package cats
package tests

import org.scalatest._
import cats.kernel.laws.discipline.SerializableTests
import cats.laws.discipline.ContravariantMonoidalTests
import cats.laws.discipline.arbitrary._
import cats.laws.discipline.eq._



class EqSuite extends FunSuite {
{
import cats.implicits._
class EqSuite extends CatsSuite {
Invariant[Eq]
Contravariant[Eq]
Semigroupal[Eq]
ContravariantSemigroupal[Eq]
ContravariantMonoidal[Eq]
}

{
import cats.instances.eq._
Invariant[Eq]
Contravariant[Eq]
Semigroupal[Eq]
ContravariantSemigroupal[Eq]
ContravariantMonoidal[Eq]
}
checkAll("Eq[Int]", ContravariantMonoidalTests[Eq].contravariantMonoidal[Int, Int, Int])
checkAll("ContravariantMonoidal[Eq]", SerializableTests.serializable(ContravariantMonoidal[Eq]))

}
9 changes: 1 addition & 8 deletions tests/src/test/scala/cats/tests/IndexedStateTSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package cats
package tests

import cats.arrow.{Profunctor, Strong}
import cats.data.{Const, EitherT, IndexedStateT, State, StateT}
import cats.data.{EitherT, IndexedStateT, State, StateT}

import cats.arrow.Profunctor
import cats.kernel.instances.tuple._
Expand Down Expand Up @@ -372,13 +372,6 @@ class IndexedStateTSuite extends CatsSuite {
SemigroupK[IndexedStateT[ListWrapper, Int, Int, ?]]
}

{
// F has a ContravariantMonoidal
val SD = ContravariantMonoidal[StateT[Const[String, ?], String, ?]]

checkAll("ContravariantMonoidal[StateT[Const[String, ?], String, ?]]", SerializableTests.serializable(SD))
}

{
implicit val iso = SemigroupalTests.Isomorphisms.invariant[State[Long, ?]]

Expand Down
29 changes: 27 additions & 2 deletions tests/src/test/scala/cats/tests/OrderSuite.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package cats
package tests


import cats.kernel.laws.discipline.OrderTests
import Helpers.Ord
import cats.kernel.laws.discipline.{OrderTests, SerializableTests}
import cats.laws.discipline.ContravariantMonoidalTests
import cats.laws.discipline.arbitrary._
import cats.laws.discipline.eq._

class OrderSuite extends CatsSuite {
{
Expand All @@ -15,6 +18,28 @@ class OrderSuite extends CatsSuite {
checkAll("Double", OrderTests[Double].order)
checkAll("Float", OrderTests[Float].order)
checkAll("Long", OrderTests[Long].order)

checkAll("Order", ContravariantMonoidalTests[Order].contravariantMonoidal[Int, Int, Int])
checkAll("ContravariantMonoidal[Order]", SerializableTests.serializable(ContravariantMonoidal[Order]))

test("order ops syntax"){
forAll { (i: Ord, j: Ord) =>
(i compare j) should ===(Order.compare(i, j))
(i min j) should ===(Order.min(i, j))
(i max j) should === (Order.max(i, j))
(i comparison j) should ===(Order.comparison(i, j))

// partial order syntax should also work when an Order instance exists
(i > j) should ===(PartialOrder.gt(i, j))
(i >= j) should ===(PartialOrder.gteqv(i, j))
(i < j) should ===(PartialOrder.lt(i, j))
(i <= j) should ===(PartialOrder.lteqv(i, j))
(i partialCompare j) should ===(PartialOrder.partialCompare(i, j))
(i tryCompare j) should ===(PartialOrder.tryCompare(i, j))
(i pmin j) should ===(PartialOrder.pmin(i, j))
(i pmax j) should ===(PartialOrder.pmax(i, j))
}
}
}

object OrderSuite {
Expand Down
35 changes: 33 additions & 2 deletions tests/src/test/scala/cats/tests/PartialOrderSuite.scala
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
package cats
package tests


import Helpers.POrd
import cats.kernel.laws.discipline.SerializableTests
import cats.laws.discipline.ContravariantMonoidalTests
import org.scalatest.Assertion
import cats.laws.discipline.arbitrary._
import cats.laws.discipline.eq._

class PartialOrderSuite extends CatsSuite {

/**
* Check that two partial compare results are "the same".
* This works around the fact that `NaN` is not equal to itself.
*/
def checkPartialCompare(res1: Double, res2: Double): Assertion = {
(res1 == res2 || (res1.isNaN && res2.isNaN)) should ===(true)
}

{
Invariant[PartialOrder]
Contravariant[PartialOrder]
}

checkAll("PartialOrder[Int]", ContravariantMonoidalTests[PartialOrder].contravariantMonoidal[Int, Int, Int])
checkAll("ContravariantMonoidal[PartialOrder]", SerializableTests.serializable(ContravariantMonoidal[PartialOrder]))

test("companion object syntax") {
forAll { (i: Int, j: Int) =>
PartialOrder.partialCompare(i, j) should ===(catsKernelStdOrderForInt.partialCompare(i, j))
checkPartialCompare(PartialOrder.partialCompare(i, j), catsKernelStdOrderForInt.partialCompare(i, j))
PartialOrder.tryCompare(i, j) should ===(catsKernelStdOrderForInt.tryCompare(i, j))
PartialOrder.pmin(i, j) should ===(catsKernelStdOrderForInt.pmin(i, j))
PartialOrder.pmax(i, j) should ===(catsKernelStdOrderForInt.pmax(i, j))
Expand All @@ -21,6 +38,20 @@ class PartialOrderSuite extends CatsSuite {
PartialOrder.gt(i, j) should ===(catsKernelStdOrderForInt.gt(i, j))
}
}

test("partial order ops syntax") {
forAll { (i: POrd, j: POrd) =>
(i > j) should ===(PartialOrder.gt(i, j))
(i >= j) should ===(PartialOrder.gteqv(i, j))
(i < j) should ===(PartialOrder.lt(i, j))
(i <= j) should ===(PartialOrder.lteqv(i, j))

checkPartialCompare(i partialCompare j, PartialOrder.partialCompare(i, j))
(i tryCompare j) should ===(PartialOrder.tryCompare(i, j))
(i pmin j) should ===(PartialOrder.pmin(i, j))
(i pmax j) should ===(PartialOrder.pmax(i, j))
}
}
}

object PartialOrderSuite {
Expand Down
3 changes: 3 additions & 0 deletions tests/src/test/scala/cats/tests/PartialOrderingSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ class PartialOrderingSuite extends CatsSuite {
checkAll("Contravariant[PartialOrdering]", ContravariantTests[PartialOrdering].contravariant[Int, Int, Int])
checkAll("Semigroupal[PartialOrdering]", SemigroupalTests[PartialOrdering].semigroupal[Int, Int, Int])
checkAll("Contravariant[PartialOrdering]", SerializableTests.serializable(Contravariant[PartialOrdering]))

checkAll("PartialOrdering[Int]", ContravariantMonoidalTests[PartialOrdering].contravariantMonoidal[Int, Int, Int])
checkAll("ContravariantMonoidal[PartialOrdering]", SerializableTests.serializable(ContravariantMonoidal[PartialOrdering]))
}

0 comments on commit 30391e8

Please sign in to comment.