From 2e7bc8aca4ca29fd42ca3e93cc775b240b372b38 Mon Sep 17 00:00:00 2001 From: ctongfei Date: Mon, 25 Mar 2019 22:48:44 -0400 Subject: [PATCH 1/3] Category[Is] instance and related tests --- core/src/main/scala/cats/evidence/Is.scala | 15 ++++++++++++++- tests/src/test/scala/cats/tests/IsSuite.scala | 5 +++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/cats/evidence/Is.scala b/core/src/main/scala/cats/evidence/Is.scala index d9b2a9c1f1..ac6a117b64 100644 --- a/core/src/main/scala/cats/evidence/Is.scala +++ b/core/src/main/scala/cats/evidence/Is.scala @@ -1,6 +1,7 @@ package cats.evidence import cats.Id +import cats.arrow._ /** * A value of `A Is B` is proof that the types `A` and `B` are the same. More @@ -65,7 +66,19 @@ abstract class Is[A, B] extends Serializable { substitute[A =:= ?](implicitly[A =:= A]) } -object Is { +sealed abstract class IsInstances { + import Is._ + + /** + * The category instance on Leibniz categories. + */ + implicit val leibniz: Category[Is] = new Category[Is] { + def id[A]: A Is A = refl[A] + def compose[A, B, C](bc: B Is C, ab: A Is B): A Is C = bc compose ab + } +} + +object Is extends IsInstances { /** * In truth, "all values of `A Is B` are `refl`". `reflAny` is that diff --git a/tests/src/test/scala/cats/tests/IsSuite.scala b/tests/src/test/scala/cats/tests/IsSuite.scala index 6d2ef5050a..3fe4a26710 100644 --- a/tests/src/test/scala/cats/tests/IsSuite.scala +++ b/tests/src/test/scala/cats/tests/IsSuite.scala @@ -1,9 +1,14 @@ package cats package tests +import cats.arrow._ +import cats.kernel.laws.discipline.SerializableTests + class IsSuite extends CatsSuite { import evidence._ + checkAll("Category[Is]", SerializableTests.serializable(Category[Is])) + test("syntax") { trait Bar From cde902caf829d33e6c7382fed7aab7385f9ae841 Mon Sep 17 00:00:00 2001 From: ctongfei Date: Mon, 25 Mar 2019 23:16:25 -0400 Subject: [PATCH 2/3] Category[Is] tests --- tests/src/test/scala/cats/tests/IsSuite.scala | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/src/test/scala/cats/tests/IsSuite.scala b/tests/src/test/scala/cats/tests/IsSuite.scala index 3fe4a26710..26f5bb827e 100644 --- a/tests/src/test/scala/cats/tests/IsSuite.scala +++ b/tests/src/test/scala/cats/tests/IsSuite.scala @@ -3,10 +3,21 @@ package tests import cats.arrow._ import cats.kernel.laws.discipline.SerializableTests +import cats.laws.discipline.CategoryTests +import org.scalacheck.{Arbitrary, Gen} class IsSuite extends CatsSuite { import evidence._ + implicit def arbIs[A, B](implicit ev: A Is B): Arbitrary[A Is B] = Arbitrary(Gen.const(ev)) + implicit def eqIs[A, B]: Eq[A Is B] = Eq.fromUniversalEquals + + trait Top { + def foo: String = this.getClass.getName + } + case class Bottom() extends Top + + checkAll("Is[Bottom, Bottom]", CategoryTests[Is].category[Bottom, Bottom, Bottom, Bottom]) checkAll("Category[Is]", SerializableTests.serializable(Category[Is])) test("syntax") { From 6db42458577b5f244a1f82df328296f4a941fc69 Mon Sep 17 00:00:00 2001 From: ctongfei Date: Thu, 28 Mar 2019 21:44:06 -0400 Subject: [PATCH 3/3] scalafmt dislike my usage of infix op --- core/src/main/scala/cats/evidence/Is.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/cats/evidence/Is.scala b/core/src/main/scala/cats/evidence/Is.scala index ac6a117b64..632f96a3e2 100644 --- a/core/src/main/scala/cats/evidence/Is.scala +++ b/core/src/main/scala/cats/evidence/Is.scala @@ -74,7 +74,7 @@ sealed abstract class IsInstances { */ implicit val leibniz: Category[Is] = new Category[Is] { def id[A]: A Is A = refl[A] - def compose[A, B, C](bc: B Is C, ab: A Is B): A Is C = bc compose ab + def compose[A, B, C](bc: B Is C, ab: A Is B): A Is C = bc.compose(ab) } }