Skip to content

Commit

Permalink
Remove RecursiveTailRecM, move stack safety checks into MonadLaws - f…
Browse files Browse the repository at this point in the history
…ixes #1278 and fixes #1283
  • Loading branch information
adelbertc committed Sep 12, 2016
1 parent 4bb7dbb commit 9faa88f
Show file tree
Hide file tree
Showing 34 changed files with 49 additions and 184 deletions.
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/Eval.scala
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,8 @@ object Eval extends EvalInstances {

private[cats] trait EvalInstances extends EvalInstances0 {

implicit val catsBimonadForEval: Bimonad[Eval] with Monad[Eval] with RecursiveTailRecM[Eval] =
new Bimonad[Eval] with Monad[Eval] with RecursiveTailRecM[Eval] {
implicit val catsBimonadForEval: Bimonad[Eval] with Monad[Eval] =
new Bimonad[Eval] with Monad[Eval] {
override def map[A, B](fa: Eval[A])(f: A => B): Eval[B] = fa.map(f)
def pure[A](a: A): Eval[A] = Now(a)
def flatMap[A, B](fa: Eval[A])(f: A => Eval[B]): Eval[B] = fa.flatMap(f)
Expand Down
24 changes: 0 additions & 24 deletions core/src/main/scala/cats/RecursiveTailRecM.scala

This file was deleted.

2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/Cokleisli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ private[data] sealed abstract class CokleisliInstances extends CokleisliInstance
implicit def catsDataArrowForCokleisli[F[_]](implicit ev: Comonad[F]): Arrow[Cokleisli[F, ?, ?]] =
new CokleisliArrow[F] { def F: Comonad[F] = ev }

implicit def catsDataMonadForCokleisli[F[_], A]: Monad[Cokleisli[F, A, ?]] with RecursiveTailRecM[Cokleisli[F, A, ?]] = new Monad[Cokleisli[F, A, ?]] with RecursiveTailRecM[Cokleisli[F, A, ?]] {
implicit def catsDataMonadForCokleisli[F[_], A]: Monad[Cokleisli[F, A, ?]] = new Monad[Cokleisli[F, A, ?]] {
def pure[B](x: B): Cokleisli[F, A, B] =
Cokleisli.pure(x)

Expand Down
3 changes: 0 additions & 3 deletions core/src/main/scala/cats/data/EitherT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,6 @@ private[data] abstract class EitherTInstances2 extends EitherTInstances3 {
implicit def catsDataMonadErrorForEitherT[F[_], L](implicit F0: Monad[F]): MonadError[EitherT[F, L, ?], L] =
new EitherTMonadError[F, L] { implicit val F = F0 }

implicit def catsDataRecursiveTailRecMForEitherT[F[_]: RecursiveTailRecM, L]: RecursiveTailRecM[EitherT[F, L, ?]] =
RecursiveTailRecM.create[EitherT[F, L, ?]]

implicit def catsDataSemigroupKForEitherT[F[_], L](implicit F0: Monad[F]): SemigroupK[EitherT[F, L, ?]] =
new EitherTSemigroupK[F, L] { implicit val F = F0 }

Expand Down
3 changes: 0 additions & 3 deletions core/src/main/scala/cats/data/IdT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,6 @@ private[data] sealed abstract class IdTInstances0 extends IdTInstances1 {
implicit val F0: Monad[F] = F
}

implicit def catsDataRecursiveTailRecMForIdT[F[_]: RecursiveTailRecM]: RecursiveTailRecM[IdT[F, ?]] =
RecursiveTailRecM.create[IdT[F, ?]]

implicit def catsDataFoldableForIdT[F[_]](implicit F: Foldable[F]): Foldable[IdT[F, ?]] =
new IdTFoldable[F] {
implicit val F0: Foldable[F] = F
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/Ior.scala
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ private[data] sealed abstract class IorInstances extends IorInstances0 {
def combine(x: Ior[A, B], y: Ior[A, B]) = x.append(y)
}

implicit def catsDataMonadForIor[A: Semigroup]: Monad[A Ior ?] with RecursiveTailRecM[A Ior ?] = new Monad[A Ior ?] with RecursiveTailRecM[A Ior ?] {
implicit def catsDataMonadForIor[A: Semigroup]: Monad[A Ior ?] = new Monad[A Ior ?] {
def pure[B](b: B): A Ior B = Ior.right(b)
def flatMap[B, C](fa: A Ior B)(f: B => A Ior C): A Ior C = fa.flatMap(f)
def tailRecM[B, C](b: B)(fn: B => Ior[A, Either[B, C]]): A Ior C = {
Expand Down
3 changes: 0 additions & 3 deletions core/src/main/scala/cats/data/Kleisli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,6 @@ private[data] sealed abstract class KleisliInstances0 extends KleisliInstances1
Kleisli[F, A, C]({ a => FlatMap[F].tailRecM(b) { f(_).run(a) } })
}

implicit def catsDataRecursiveTailRecMForKleisli[F[_]: RecursiveTailRecM, A]: RecursiveTailRecM[Kleisli[F, A, ?]] =
RecursiveTailRecM.create[Kleisli[F, A, ?]]

implicit def catsDataSemigroupForKleisli[F[_], A, B](implicit M: Semigroup[F[B]]): Semigroup[Kleisli[F, A, B]] =
new KleisliSemigroup[F, A, B] { def FB: Semigroup[F[B]] = M }

Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/data/NonEmptyList.scala
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ object NonEmptyList extends NonEmptyListInstances {
private[data] sealed trait NonEmptyListInstances extends NonEmptyListInstances0 {

implicit val catsDataInstancesForNonEmptyList: SemigroupK[NonEmptyList] with Reducible[NonEmptyList]
with Comonad[NonEmptyList] with Traverse[NonEmptyList] with Monad[NonEmptyList] with RecursiveTailRecM[NonEmptyList] =
with Comonad[NonEmptyList] with Traverse[NonEmptyList] with Monad[NonEmptyList] =
new NonEmptyReducible[NonEmptyList, List] with SemigroupK[NonEmptyList] with Comonad[NonEmptyList]
with Traverse[NonEmptyList] with Monad[NonEmptyList] with RecursiveTailRecM[NonEmptyList] {
with Traverse[NonEmptyList] with Monad[NonEmptyList] {

def combineK[A](a: NonEmptyList[A], b: NonEmptyList[A]): NonEmptyList[A] =
a concat b
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/data/NonEmptyVector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ final class NonEmptyVector[A] private (val toVector: Vector[A]) extends AnyVal {
private[data] sealed trait NonEmptyVectorInstances {

implicit val catsDataInstancesForNonEmptyVector: SemigroupK[NonEmptyVector] with Reducible[NonEmptyVector]
with Comonad[NonEmptyVector] with Traverse[NonEmptyVector] with Monad[NonEmptyVector] with RecursiveTailRecM[NonEmptyVector] =
with Comonad[NonEmptyVector] with Traverse[NonEmptyVector] with Monad[NonEmptyVector] =
new NonEmptyReducible[NonEmptyVector, Vector] with SemigroupK[NonEmptyVector] with Comonad[NonEmptyVector]
with Traverse[NonEmptyVector] with Monad[NonEmptyVector] with RecursiveTailRecM[NonEmptyVector] {
with Traverse[NonEmptyVector] with Monad[NonEmptyVector] {

def combineK[A](a: NonEmptyVector[A], b: NonEmptyVector[A]): NonEmptyVector[A] =
a concatNev b
Expand Down
3 changes: 0 additions & 3 deletions core/src/main/scala/cats/data/OneAnd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,6 @@ private[data] sealed trait OneAndInstances extends OneAndLowPriority2 {
go(a, Nil)
}
}

implicit def catsDataOneAnd[F[_]: RecursiveTailRecM]: RecursiveTailRecM[OneAnd[F, ?]] =
RecursiveTailRecM.create[OneAnd[F, ?]]
}

private[data] trait OneAndLowPriority0 {
Expand Down
3 changes: 0 additions & 3 deletions core/src/main/scala/cats/data/OptionT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,6 @@ private[data] sealed trait OptionTInstances0 extends OptionTInstances1 {
implicit def catsDataMonadErrorForOptionT[F[_], E](implicit F0: MonadError[F, E]): MonadError[OptionT[F, ?], E] =
new OptionTMonadError[F, E] { implicit val F = F0 }

implicit def catsDataRecursiveTailRecMForOptionT[F[_]](implicit F: RecursiveTailRecM[F]): RecursiveTailRecM[OptionT[F, ?]] =
RecursiveTailRecM.create[OptionT[F, ?]]

implicit def catsDataSemigroupKForOptionT[F[_]](implicit F0: Monad[F]): SemigroupK[OptionT[F, ?]] =
new OptionTSemigroupK[F] { implicit val F = F0 }

Expand Down
2 changes: 0 additions & 2 deletions core/src/main/scala/cats/data/StateT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,6 @@ private[data] sealed trait StateTInstances2 {
implicit def catsDataMonadForStateT[F[_], S](implicit F0: Monad[F]): Monad[StateT[F, S, ?]] =
new StateTMonad[F, S] { implicit def F = F0 }

implicit def catsDataRecursiveTailRecMForStateT[F[_]: RecursiveTailRecM, S]: RecursiveTailRecM[StateT[F, S, ?]] = RecursiveTailRecM.create[StateT[F, S, ?]]

implicit def catsDataSemigroupKForStateT[F[_], S](implicit F0: Monad[F], G0: SemigroupK[F]): SemigroupK[StateT[F, S, ?]] =
new StateTSemigroupK[F, S] { implicit def F = F0; implicit def G = G0 }
}
Expand Down
3 changes: 0 additions & 3 deletions core/src/main/scala/cats/data/WriterT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,6 @@ private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2

implicit def catsDataCoflatMapForWriterTId[L]: CoflatMap[WriterT[Id, L, ?]] =
catsDataCoflatMapForWriterT[Id, L]

implicit def catsDataRecursiveTailRecMForWriterT1[F[_]: RecursiveTailRecM, L]: RecursiveTailRecM[WriterT[F, L, ?]] =
RecursiveTailRecM.create[WriterT[F, L, ?]]
}

private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 {
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/instances/either.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances {
}

// scalastyle:off method.length
implicit def catsStdInstancesForEither[A]: MonadError[Either[A, ?], A] with Traverse[Either[A, ?]] with RecursiveTailRecM[Either[A, ?]] =
new MonadError[Either[A, ?], A] with Traverse[Either[A, ?]] with RecursiveTailRecM[Either[A, ?]] {
implicit def catsStdInstancesForEither[A]: MonadError[Either[A, ?], A] with Traverse[Either[A, ?]] =
new MonadError[Either[A, ?], A] with Traverse[Either[A, ?]] {
def pure[B](b: B): Either[A, B] = Right(b)

def flatMap[B, C](fa: Either[A, B])(f: B => Either[A, C]): Either[A, C] =
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/scala/cats/instances/function.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ trait FunctionInstances extends cats.kernel.instances.FunctionInstances

private[instances] sealed trait Function0Instances {

implicit val catsStdBimonadForFunction0: Bimonad[Function0] with RecursiveTailRecM[Function0] =
new Bimonad[Function0] with RecursiveTailRecM[Function0] {
implicit val catsStdBimonadForFunction0: Bimonad[Function0] =
new Bimonad[Function0] {
def extract[A](x: () => A): A = x()

def coflatMap[A, B](fa: () => A)(f: (() => A) => B): () => B =
Expand Down Expand Up @@ -42,8 +42,8 @@ private[instances] sealed trait Function1Instances {
fa.compose(f)
}

implicit def catsStdMonadReaderForFunction1[T1]: MonadReader[T1 => ?, T1] with RecursiveTailRecM[T1 => ?] =
new MonadReader[T1 => ?, T1] with RecursiveTailRecM[T1 => ?] {
implicit def catsStdMonadReaderForFunction1[T1]: MonadReader[T1 => ?, T1] =
new MonadReader[T1 => ?, T1] {
def pure[R](r: R): T1 => R = _ => r

def flatMap[R1, R2](fa: T1 => R1)(f: R1 => T1 => R2): T1 => R2 =
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/instances/future.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import scala.concurrent.{ExecutionContext, Future}

trait FutureInstances extends FutureInstances1 {

implicit def catsStdInstancesForFuture(implicit ec: ExecutionContext): MonadError[Future, Throwable] with CoflatMap[Future] with Monad[Future] with RecursiveTailRecM[Future] =
new FutureCoflatMap with MonadError[Future, Throwable] with Monad[Future] with RecursiveTailRecM[Future] {
implicit def catsStdInstancesForFuture(implicit ec: ExecutionContext): MonadError[Future, Throwable] with CoflatMap[Future] with Monad[Future] =
new FutureCoflatMap with MonadError[Future, Throwable] with Monad[Future] {
def pure[A](x: A): Future[A] = Future.successful(x)

def flatMap[A, B](fa: Future[A])(f: A => Future[B]): Future[B] = fa.flatMap(f)
Expand Down
5 changes: 2 additions & 3 deletions core/src/main/scala/cats/instances/list.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import scala.collection.mutable.ListBuffer

trait ListInstances extends cats.kernel.instances.ListInstances {

implicit val catsStdInstancesForList: TraverseFilter[List] with MonadCombine[List] with Monad[List] with CoflatMap[List] with RecursiveTailRecM[List] =
new TraverseFilter[List] with MonadCombine[List] with Monad[List] with CoflatMap[List] with RecursiveTailRecM[List] {

implicit val catsStdInstancesForList: TraverseFilter[List] with MonadCombine[List] with Monad[List] with CoflatMap[List] =
new TraverseFilter[List] with MonadCombine[List] with Monad[List] with CoflatMap[List] {
def empty[A]: List[A] = Nil

def combineK[A](x: List[A], y: List[A]): List[A] = x ++ y
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/instances/map.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ trait MapInstances extends cats.kernel.instances.MapInstances {
}

// scalastyle:off method.length
implicit def catsStdInstancesForMap[K]: TraverseFilter[Map[K, ?]] with FlatMap[Map[K, ?]] with RecursiveTailRecM[Map[K, ?]] =
new TraverseFilter[Map[K, ?]] with FlatMap[Map[K, ?]] with RecursiveTailRecM[Map[K, ?]] {
implicit def catsStdInstancesForMap[K]: TraverseFilter[Map[K, ?]] with FlatMap[Map[K, ?]] =
new TraverseFilter[Map[K, ?]] with FlatMap[Map[K, ?]] {

override def traverse[G[_], A, B](fa: Map[K, A])(f: A => G[B])(implicit G: Applicative[G]): G[Map[K, B]] = {
val gba: Eval[G[Map[K, B]]] = Always(G.pure(Map.empty))
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/instances/option.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import scala.annotation.tailrec

trait OptionInstances extends cats.kernel.instances.OptionInstances {

implicit val catsStdInstancesForOption: TraverseFilter[Option] with MonadError[Option, Unit] with MonadCombine[Option] with Monad[Option] with CoflatMap[Option] with Alternative[Option] with RecursiveTailRecM[Option] =
new TraverseFilter[Option] with MonadError[Option, Unit] with MonadCombine[Option] with Monad[Option] with CoflatMap[Option] with Alternative[Option] with RecursiveTailRecM[Option] {
implicit val catsStdInstancesForOption: TraverseFilter[Option] with MonadError[Option, Unit] with MonadCombine[Option] with Monad[Option] with CoflatMap[Option] with Alternative[Option] =
new TraverseFilter[Option] with MonadError[Option, Unit] with MonadCombine[Option] with Monad[Option] with CoflatMap[Option] with Alternative[Option] {

def empty[A]: Option[A] = None

Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/instances/stream.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import cats.syntax.show._
import scala.annotation.tailrec

trait StreamInstances extends cats.kernel.instances.StreamInstances {
implicit val catsStdInstancesForStream: TraverseFilter[Stream] with MonadCombine[Stream] with CoflatMap[Stream] with RecursiveTailRecM[Stream] =
new TraverseFilter[Stream] with MonadCombine[Stream] with CoflatMap[Stream] with RecursiveTailRecM[Stream] {
implicit val catsStdInstancesForStream: TraverseFilter[Stream] with MonadCombine[Stream] with CoflatMap[Stream] =
new TraverseFilter[Stream] with MonadCombine[Stream] with CoflatMap[Stream] {

def empty[A]: Stream[A] = Stream.Empty

Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/instances/try.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import scala.annotation.tailrec
trait TryInstances extends TryInstances1 {

// scalastyle:off method.length
implicit def catsStdInstancesForTry: MonadError[Try, Throwable] with CoflatMap[Try] with Traverse[Try] with Monad[Try] with RecursiveTailRecM[Try] =
new TryCoflatMap with MonadError[Try, Throwable] with Traverse[Try] with Monad[Try] with RecursiveTailRecM[Try] {
implicit def catsStdInstancesForTry: MonadError[Try, Throwable] with CoflatMap[Try] with Traverse[Try] with Monad[Try] =
new TryCoflatMap with MonadError[Try, Throwable] with Traverse[Try] with Monad[Try] {
def pure[A](x: A): Try[A] = Success(x)

override def product[A, B](ta: Try[A], tb: Try[B]): Try[(A, B)] = (ta, tb) match {
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/scala/cats/instances/tuple.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,18 @@ sealed trait Tuple2Instances extends Tuple2Instances1 {
}

sealed trait Tuple2Instances1 extends Tuple2Instances2 {
implicit def catsStdMonadForTuple2[X](implicit MX: Monoid[X]): Monad[(X, ?)] with RecursiveTailRecM[(X, ?)] =
implicit def catsStdMonadForTuple2[X](implicit MX: Monoid[X]): Monad[(X, ?)] =
new FlatMapTuple2[X](MX) with Monad[(X, ?)] {
def pure[A](a: A): (X, A) = (MX.empty, a)
}
}

sealed trait Tuple2Instances2 {
implicit def catsStdFlatMapForTuple2[X](implicit SX: Semigroup[X]): FlatMap[(X, ?)] with RecursiveTailRecM[(X, ?)]=
implicit def catsStdFlatMapForTuple2[X](implicit SX: Semigroup[X]): FlatMap[(X, ?)] =
new FlatMapTuple2[X](SX)
}

private[instances] class FlatMapTuple2[X](s: Semigroup[X]) extends FlatMap[(X, ?)] with RecursiveTailRecM[(X, ?)] {
private[instances] class FlatMapTuple2[X](s: Semigroup[X]) extends FlatMap[(X, ?)] {
override def ap[A, B](ff: (X, A => B))(fa: (X, A)): (X, B) = {
val x = s.combine(ff._1, fa._1)
val b = ff._2(fa._2)
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/instances/vector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import scala.collection.+:
import scala.collection.immutable.VectorBuilder

trait VectorInstances extends cats.kernel.instances.VectorInstances {
implicit val catsStdInstancesForVector: TraverseFilter[Vector] with MonadCombine[Vector] with CoflatMap[Vector] with RecursiveTailRecM[Vector] =
new TraverseFilter[Vector] with MonadCombine[Vector] with CoflatMap[Vector] with RecursiveTailRecM[Vector] {
implicit val catsStdInstancesForVector: TraverseFilter[Vector] with MonadCombine[Vector] with CoflatMap[Vector] =
new TraverseFilter[Vector] with MonadCombine[Vector] with CoflatMap[Vector] {

def empty[A]: Vector[A] = Vector.empty[A]

Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ package object cats {
* encodes pure unary function application.
*/
type Id[A] = A
implicit val catsInstancesForId: Bimonad[Id] with Monad[Id] with Traverse[Id] with RecursiveTailRecM[Id] =
new Bimonad[Id] with Monad[Id] with Traverse[Id] with RecursiveTailRecM[Id] {
implicit val catsInstancesForId: Bimonad[Id] with Monad[Id] with Traverse[Id] =
new Bimonad[Id] with Monad[Id] with Traverse[Id] {
def pure[A](a: A): A = a
def extract[A](a: A): A = a
def flatMap[A, B](a: A)(f: A => B): B = f(a)
Expand Down
6 changes: 6 additions & 0 deletions laws/src/main/scala/cats/laws/MonadLaws.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ trait MonadLaws[F[_]] extends ApplicativeLaws[F] with FlatMapLaws[F] {
*/
def mapFlatMapCoherence[A, B](fa: F[A], f: A => B): IsEq[F[B]] =
fa.flatMap(a => F.pure(f(a))) <-> fa.map(f)

val tailRecMStackSafety: IsEq[F[Int]] = {
val n = 50000
val res = F.tailRecM(0)(i => F.pure(if (i < n) Either.left(i + 1) else Either.right(i)))
res <-> F.pure(n)
}
}

object MonadLaws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ trait BimonadTests[F[_]] extends MonadTests[F] with ComonadTests[F] {
EqFB: Eq[F[B]],
EqFC: Eq[F[C]],
EqFABC: Eq[F[(A, B, C)]],
EqFInt: Eq[F[Int]],
iso: Isomorphisms[F]
): RuleSet = {
new RuleSet {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ trait MonadCombineTests[F[_]] extends MonadFilterTests[F] with AlternativeTests[
EqFB: Eq[F[B]],
EqFC: Eq[F[C]],
EqFABC: Eq[F[(A, B, C)]],
EqFInt: Eq[F[Int]],
iso: Isomorphisms[F]
): RuleSet = {
new RuleSet {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ trait MonadErrorTests[F[_], E] extends ApplicativeErrorTests[F, E] with MonadTes
EqFEitherEA: Eq[F[Either[E, A]]],
EqEitherTFEA: Eq[EitherT[F, E, A]],
EqFABC: Eq[F[(A, B, C)]],
EqFInt: Eq[F[Int]],
iso: Isomorphisms[F]
): RuleSet = {
new RuleSet {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ trait MonadFilterTests[F[_]] extends MonadTests[F] with FunctorFilterTests[F] {
EqFB: Eq[F[B]],
EqFC: Eq[F[C]],
EqFABC: Eq[F[(A, B, C)]],
EqFInt: Eq[F[Int]],
iso: Isomorphisms[F]
): RuleSet = {
new RuleSet {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ trait MonadReaderTests[F[_], R] extends MonadTests[F] {
EqFC: Eq[F[C]],
EqFR: Eq[F[R]],
EqFABC: Eq[F[(A, B, C)]],
EqFInt: Eq[F[Int]],
iso: Isomorphisms[F]
): RuleSet = {
new RuleSet {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ trait MonadStateTests[F[_], S] extends MonadTests[F] {
EqFUnit: Eq[F[Unit]],
EqFS: Eq[F[S]],
EqFABC: Eq[F[(A, B, C)]],
EqFInt: Eq[F[Int]],
iso: Isomorphisms[F]
): RuleSet = {
new RuleSet {
Expand Down
4 changes: 3 additions & 1 deletion laws/src/main/scala/cats/laws/discipline/MonadTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ trait MonadTests[F[_]] extends ApplicativeTests[F] with FlatMapTests[F] {
EqFB: Eq[F[B]],
EqFC: Eq[F[C]],
EqFABC: Eq[F[(A, B, C)]],
EqFInt: Eq[F[Int]],
iso: Isomorphisms[F]
): RuleSet = {
new RuleSet {
Expand All @@ -29,7 +30,8 @@ trait MonadTests[F[_]] extends ApplicativeTests[F] with FlatMapTests[F] {
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] _)
"map flatMap coherence" -> forAll(laws.mapFlatMapCoherence[A, B] _),
"tailRecM stack safety" -> laws.tailRecMStackSafety
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ trait MonadWriterTests[F[_], W] extends MonadTests[F] {
EqFC: Eq[F[C]],
EqFU: Eq[F[Unit]],
EqFABC: Eq[F[(A, B, C)]],
EqFInt: Eq[F[Int]],
WA: Arbitrary[W],
WM: Monoid[W],
iso: Isomorphisms[F]
Expand Down
Loading

0 comments on commit 9faa88f

Please sign in to comment.