diff --git a/build.sbt b/build.sbt index 85af356214..387bb4a6ee 100644 --- a/build.sbt +++ b/build.sbt @@ -264,7 +264,7 @@ lazy val laws = crossProject.crossType(CrossType.Pure) .settings(catsSettings:_*) .settings(disciplineDependencies:_*) .configureCross(disableScoverage210Jvm) - .settings(libraryDependencies ++= Seq("org.typelevel" %%% "catalysts-platform" % "0.0.4")) + .settings(testingDependencies: _*) .jsSettings(commonJsSettings:_*) .jvmSettings(commonJvmSettings:_*) .jsSettings(coverageEnabled := false) diff --git a/laws/src/main/scala/cats/laws/discipline/MonadTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadTests.scala index ecca51468c..7dfebf3cc5 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonadTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonadTests.scala @@ -37,6 +37,34 @@ trait MonadTests[F[_]] extends ApplicativeTests[F] with FlatMapTests[F] { ) ++ (if (Platform.isJvm) Seq[(String, Prop)]("tailRecM stack safety" -> laws.tailRecMStackSafety) else Seq.empty) } } + + def stackUnsafeMonad[A: Arbitrary: Eq, B: Arbitrary: Eq, C: Arbitrary: Eq](implicit + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + EqFInt: Eq[F[Int]], + iso: Isomorphisms[F] + ): RuleSet = { + new RuleSet { + def name: String = "monad (stack-unsafe)" + def bases: Seq[(String, RuleSet)] = Nil + def parents: Seq[RuleSet] = Seq(applicative[A, B, C], flatMap[A, B, C]) + def props: Seq[(String, Prop)] = Seq( + "monad left identity" -> forAll(laws.monadLeftIdentity[A, B] _), + "monad right identity" -> forAll(laws.monadRightIdentity[A] _), + "map flatMap coherence" -> forAll(laws.mapFlatMapCoherence[A, B] _) + ) + } + } } object MonadTests { diff --git a/laws/src/test/scala/cats/laws/discipline/MonadTestsTests.scala b/laws/src/test/scala/cats/laws/discipline/MonadTestsTests.scala new file mode 100644 index 0000000000..031c826968 --- /dev/null +++ b/laws/src/test/scala/cats/laws/discipline/MonadTestsTests.scala @@ -0,0 +1,15 @@ +package cats +package laws +package discipline + +import cats.instances.all._ +import cats.laws.discipline.arbitrary._ +import org.scalatest.FunSuite +import org.typelevel.discipline.scalatest.Discipline + +class MonadTestsTests extends FunSuite with Discipline { + // We don't use `stackUnsafeMonad` in our laws checking for instances in Cats, + // so we confirm here that the laws pass for `Eval` (the monad instance for + // which is actually stack safe, like all other monad instances in Cats.) + checkAll("Eval[Int]", MonadTests[Eval].stackUnsafeMonad[Int, Int, Int]) +}