Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Luka jcb add monoidal to monoid #3

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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, ?]] {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already provided by Applicative

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]))
}