From 5805c613f45fdc239be33cb154dc94a55275bed0 Mon Sep 17 00:00:00 2001 From: Filippo Mariotti Date: Fri, 16 Nov 2018 00:07:24 +0000 Subject: [PATCH 1/3] Fixed priority, added test --- core/src/main/scala/cats/data/OptionT.scala | 14 ++++++++++---- tests/src/test/scala/cats/tests/OptionTSuite.scala | 6 ++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/cats/data/OptionT.scala b/core/src/main/scala/cats/data/OptionT.scala index 1b5b19c84d..8602996b4a 100644 --- a/core/src/main/scala/cats/data/OptionT.scala +++ b/core/src/main/scala/cats/data/OptionT.scala @@ -270,8 +270,14 @@ sealed abstract private[data] class OptionTInstances extends OptionTInstances0 { } sealed abstract private[data] class OptionTInstances0 extends OptionTInstances1 { - implicit def catsDataMonadErrorMonadForOptionT[F[_]](implicit F0: Monad[F]): MonadError[OptionT[F, ?], Unit] = - new OptionTMonadErrorMonad[F] { implicit val F = F0 } + + // the Dummy type is to make this one more specific than catsDataMonadErrorMonadForOptionT on 2.13.x + // see https://github.com/typelevel/cats/pull/2335#issuecomment-408249775 + implicit def catsDataMonadErrorForOptionT[F[_], E](implicit F0: MonadError[F, E]): MonadError[OptionT[F, ?], E] { type Dummy } = + new OptionTMonadError[F, E] { + type Dummy + implicit val F = F0 + } implicit def catsDataContravariantMonoidalForOptionT[F[_]]( implicit F0: ContravariantMonoidal[F] @@ -303,8 +309,8 @@ sealed abstract private[data] class OptionTInstances1 extends OptionTInstances2 implicit def catsDataEqForOptionT[F[_], A](implicit F0: Eq[F[Option[A]]]): Eq[OptionT[F, A]] = new OptionTEq[F, A] { implicit val F = F0 } - implicit def catsDataMonadErrorForOptionT[F[_], E](implicit F0: MonadError[F, E]): MonadError[OptionT[F, ?], E] = - new OptionTMonadError[F, E] { implicit val F = F0 } + implicit def catsDataMonadErrorMonadForOptionT[F[_]](implicit F0: Monad[F]): MonadError[OptionT[F, ?], Unit] = + new OptionTMonadErrorMonad[F] { implicit val F = F0 } } sealed abstract private[data] class OptionTInstances2 extends OptionTInstances3 { diff --git a/tests/src/test/scala/cats/tests/OptionTSuite.scala b/tests/src/test/scala/cats/tests/OptionTSuite.scala index 9b9e25160d..6edb9ef5d2 100644 --- a/tests/src/test/scala/cats/tests/OptionTSuite.scala +++ b/tests/src/test/scala/cats/tests/OptionTSuite.scala @@ -184,6 +184,12 @@ class OptionTSuite extends CatsSuite { checkAll("MonadError[OptionT[List, ?]]", SerializableTests.serializable(MonadError[OptionT[ListWrapper, ?], Unit])) } + test("MonadError[OptionT[F, ?], E] instance has higher priority than MonadError[OptionT[F, ?], Unit]") { + + def shouldCompile[F[_]: MonadError[?[_], E], E](x: OptionT[F, Int], e: E): OptionT[F, Int] = + x.ensure(e)(_ => true) + } + test("fold and cata consistent") { forAll { (o: OptionT[List, Int], s: String, f: Int => String) => o.fold(s)(f) should ===(o.cata(s, f)) From 3d3f8087f1c45b1a1dc5606433a460b6b46789bc Mon Sep 17 00:00:00 2001 From: Filippo Mariotti Date: Fri, 16 Nov 2018 00:54:07 +0000 Subject: [PATCH 2/3] Added mima exceptions and tests --- binCompatTest/src/main/scala/catsBC/MimaExceptions.scala | 4 +++- build.sbt | 5 +++-- core/src/main/scala/cats/data/OptionT.scala | 4 +++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/binCompatTest/src/main/scala/catsBC/MimaExceptions.scala b/binCompatTest/src/main/scala/catsBC/MimaExceptions.scala index 8beaa353be..db73cf406f 100644 --- a/binCompatTest/src/main/scala/catsBC/MimaExceptions.scala +++ b/binCompatTest/src/main/scala/catsBC/MimaExceptions.scala @@ -18,7 +18,9 @@ object MimaExceptions { cats.data.Kleisli.catsDataCommutativeFlatMapForKleisli[Option, Int], cats.data.IRWST.catsDataStrongForIRWST[List, Int, Int, Int], cats.data.OptionT.catsDataMonadErrorMonadForOptionT[List], - FunctionK.lift(headOption) + FunctionK.lift(headOption), + cats.data.OptionT.catsDataMonadErrorForOptionT[Either[String, ?], String], + cats.data.OptionT[Either[String, ?], Int](Right(Some(17))).ensure("error")(_ => true) ) } diff --git a/build.sbt b/build.sbt index 69122d431a..4655c9d8ea 100644 --- a/build.sbt +++ b/build.sbt @@ -280,7 +280,8 @@ def mimaSettings(moduleName: String) = exclude[DirectMissingMethodProblem]("cats.data.KleisliInstances1.catsDataCommutativeArrowForKleisli"), exclude[DirectMissingMethodProblem]("cats.data.KleisliInstances4.catsDataCommutativeFlatMapForKleisli"), exclude[DirectMissingMethodProblem]("cats.data.IRWSTInstances1.catsDataStrongForIRWST"), - exclude[DirectMissingMethodProblem]("cats.data.OptionTInstances1.catsDataMonadErrorMonadForOptionT") + exclude[DirectMissingMethodProblem]("cats.data.OptionTInstances1.catsDataMonadErrorMonadForOptionT"), + exclude[DirectMissingMethodProblem]("cats.data.OptionTInstances1.catsDataMonadErrorForOptionT") ) ++ // Only compile-time abstractions (macros) allowed here Seq( exclude[IncompatibleMethTypeProblem]("cats.arrow.FunctionKMacros.lift"), @@ -562,7 +563,7 @@ lazy val binCompatTest = project .disablePlugins(CoursierPlugin) .settings(noPublishSettings) .settings( - addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.7"), + addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.8"), libraryDependencies ++= List( { if (priorTo2_13(scalaVersion.value)) diff --git a/core/src/main/scala/cats/data/OptionT.scala b/core/src/main/scala/cats/data/OptionT.scala index 8602996b4a..08d5174092 100644 --- a/core/src/main/scala/cats/data/OptionT.scala +++ b/core/src/main/scala/cats/data/OptionT.scala @@ -273,7 +273,9 @@ sealed abstract private[data] class OptionTInstances0 extends OptionTInstances1 // the Dummy type is to make this one more specific than catsDataMonadErrorMonadForOptionT on 2.13.x // see https://github.com/typelevel/cats/pull/2335#issuecomment-408249775 - implicit def catsDataMonadErrorForOptionT[F[_], E](implicit F0: MonadError[F, E]): MonadError[OptionT[F, ?], E] { type Dummy } = + implicit def catsDataMonadErrorForOptionT[F[_], E]( + implicit F0: MonadError[F, E] + ): MonadError[OptionT[F, ?], E] { type Dummy } = new OptionTMonadError[F, E] { type Dummy implicit val F = F0 From d5bc2e9da6519ca4252b66cb76da96e251603afd Mon Sep 17 00:00:00 2001 From: Filippo Mariotti Date: Sat, 17 Nov 2018 18:13:15 +0000 Subject: [PATCH 3/3] Format and comma --- binCompatTest/src/main/scala/catsBC/MimaExceptions.scala | 3 +-- build.sbt | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/binCompatTest/src/main/scala/catsBC/MimaExceptions.scala b/binCompatTest/src/main/scala/catsBC/MimaExceptions.scala index ceda327d4b..b86c85e6f5 100644 --- a/binCompatTest/src/main/scala/catsBC/MimaExceptions.scala +++ b/binCompatTest/src/main/scala/catsBC/MimaExceptions.scala @@ -20,9 +20,8 @@ object MimaExceptions { cats.data.OptionT.catsDataMonadErrorMonadForOptionT[List], FunctionK.lift(headOption), cats.data.OptionT.catsDataMonadErrorForOptionT[Either[String, ?], String], - cats.data.OptionT[Either[String, ?], Int](Right(Some(17))).ensure("error")(_ => true) + cats.data.OptionT[Either[String, ?], Int](Right(Some(17))).ensure("error")(_ => true), "blah".leftNec[Int], List(Some(4), None).nested ) - } diff --git a/build.sbt b/build.sbt index dd04e33fa1..f00f9861aa 100644 --- a/build.sbt +++ b/build.sbt @@ -285,7 +285,6 @@ def mimaSettings(moduleName: String) = //These 2 things are `.value` on a Ops class (which shouldn't have ever been exposed) - See #2514 and #2613. exclude[DirectMissingMethodProblem]("cats.syntax.EitherIdOpsBinCompat0.value"), exclude[DirectMissingMethodProblem]("cats.syntax.NestedIdOps.value") - ) ++ // Only compile-time abstractions (macros) allowed here Seq( exclude[IncompatibleMethTypeProblem]("cats.arrow.FunctionKMacros.lift"),