diff --git a/core/src/main/scala/cats/Alternative.scala b/core/src/main/scala/cats/Alternative.scala index 343de9ced40..def09bb1bfc 100644 --- a/core/src/main/scala/cats/Alternative.scala +++ b/core/src/main/scala/cats/Alternative.scala @@ -3,6 +3,25 @@ package cats import simulacrum.typeclass @typeclass trait Alternative[F[_]] extends Applicative[F] with MonoidK[F] { self => + /** + * Fold over the inner structure to combine all of the values with + * our combine method inherited from MonoidK. The result is for us + * to accumulate all of the "interesting" values of the inner G, so + * if G is Option, we collect all the Some values, if G is Either, + * we collect all the Right values, etc. + */ + def unite[G[_], A](fga: F[G[A]])(implicit FM: Monad[F], G: Foldable[G]): F[A] = + FM.flatMap(fga) { ga => + G.foldLeft(ga, empty[A])((acc, a) => combineK(acc, pure(a))) + } + + /** Separate the inner foldable values into the "lefts" and "rights" */ + def separate[G[_, _], A, B](fgab: F[G[A, B]])(implicit FM: Monad[F], G: Bifoldable[G]): (F[A], F[B]) = { + val as = FM.flatMap(fgab)(gab => G.bifoldMap(gab)(pure, _ => empty[A])(algebra[A])) + val bs = FM.flatMap(fgab)(gab => G.bifoldMap(gab)(_ => empty[B], pure)(algebra[B])) + (as, bs) + } + override def compose[G[_]: Applicative]: Alternative[λ[α => F[G[α]]]] = new ComposedAlternative[F, G] { val F = self diff --git a/core/src/main/scala/cats/Composed.scala b/core/src/main/scala/cats/Composed.scala index b231f13731b..6b886af3d08 100644 --- a/core/src/main/scala/cats/Composed.scala +++ b/core/src/main/scala/cats/Composed.scala @@ -79,22 +79,6 @@ private[cats] trait ComposedNonEmptyTraverse[F[_], G[_]] extends NonEmptyTravers F.nonEmptyTraverse(fga)(ga => G.nonEmptyTraverse(ga)(f)) } -private[cats] trait ComposedTraverseFilter[F[_], G[_]] extends TraverseFilter[λ[α => F[G[α]]]] with ComposedTraverse[F, G] { - def F: Traverse[F] - def G: TraverseFilter[G] - - override def traverseFilter[H[_]: Applicative, A, B](fga: F[G[A]])(f: A => H[Option[B]]): H[F[G[B]]] = - F.traverse[H, G[A], G[B]](fga)(ga => G.traverseFilter(ga)(f)) -} - -private[cats] trait ComposedFunctorFilter[F[_], G[_]] extends FunctorFilter[λ[α => F[G[α]]]] with ComposedFunctor[F, G] { - def F: Functor[F] - def G: FunctorFilter[G] - - override def mapFilter[A, B](fga: F[G[A]])(f: A => Option[B]): F[G[B]] = - F.map(fga)(G.mapFilter(_)(f)) -} - private[cats] trait ComposedReducible[F[_], G[_]] extends Reducible[λ[α => F[G[α]]]] with ComposedFoldable[F, G] { outer => def F: Reducible[F] def G: Reducible[G] diff --git a/core/src/main/scala/cats/Functor.scala b/core/src/main/scala/cats/Functor.scala index 5199ab48abc..fb6a0588393 100644 --- a/core/src/main/scala/cats/Functor.scala +++ b/core/src/main/scala/cats/Functor.scala @@ -68,12 +68,6 @@ import simulacrum.typeclass val G = Functor[G] } - def composeFilter[G[_]: FunctorFilter]: FunctorFilter[λ[α => F[G[α]]]] = - new ComposedFunctorFilter[F, G] { - val F = self - val G = FunctorFilter[G] - } - override def composeContravariant[G[_]: Contravariant]: Contravariant[λ[α => F[G[α]]]] = new ComposedCovariantContravariant[F, G] { val F = self diff --git a/core/src/main/scala/cats/FunctorFilter.scala b/core/src/main/scala/cats/FunctorFilter.scala deleted file mode 100644 index cbbb5755de0..00000000000 --- a/core/src/main/scala/cats/FunctorFilter.scala +++ /dev/null @@ -1,62 +0,0 @@ -package cats - -import simulacrum.typeclass - -@typeclass trait FunctorFilter[F[_]] extends Functor[F] { - - /** - * A combined [[map]] and [[filter]]. Filtering is handled via `Option` - * instead of `Boolean` such that the output type `B` can be different than - * the input type `A`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val m: Map[Int, String] = Map(1 -> "one", 3 -> "three") - * scala> val l: List[Int] = List(1, 2, 3, 4) - * scala> def asString(i: Int): Option[String] = m.get(i) - * scala> l.mapFilter(i => m.get(i)) - * res0: List[String] = List(one, three) - * }}} - */ - def mapFilter[A, B](fa: F[A])(f: A => Option[B]): F[B] - - /** - * Similar to [[mapFilter]] but uses a partial function instead of a function - * that returns an `Option`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l: List[Int] = List(1, 2, 3, 4) - * scala> FunctorFilter[List].collect(l){ - * | case 1 => "one" - * | case 3 => "three" - * | } - * res0: List[String] = List(one, three) - * }}} - */ - def collect[A, B](fa: F[A])(f: PartialFunction[A, B]): F[B] = - mapFilter(fa)(f.lift) - - /** - * "Flatten" out a structure by collapsing `Option`s. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l: List[Option[Int]] = List(Some(1), None, Some(3), None) - * scala> l.flattenOption - * res0: List[Int] = List(1, 3) - * }}} - */ - def flattenOption[A](fa: F[Option[A]]): F[A] = mapFilter(fa)(identity) - - /** - * Apply a filter to a structure such that the output structure contains all - * `A` elements in the input structure that satisfy the predicate `f` but none - * that don't. - */ - def filter[A](fa: F[A])(f: A => Boolean): F[A] = - mapFilter(fa)(a => if (f(a)) Some(a) else None) -} diff --git a/core/src/main/scala/cats/MonadCombine.scala b/core/src/main/scala/cats/MonadCombine.scala deleted file mode 100644 index a418cba774b..00000000000 --- a/core/src/main/scala/cats/MonadCombine.scala +++ /dev/null @@ -1,28 +0,0 @@ -package cats - -import simulacrum.typeclass - -/** - * The combination of a Monad with a MonoidK - */ -@typeclass trait MonadCombine[F[_]] extends MonadFilter[F] with Alternative[F] { - - /** - * Fold over the inner structure to combine all of the values with - * our combine method inherited from MonoidK. The result is for us - * to accumulate all of the "interesting" values of the inner G, so - * if G is Option, we collect all the Some values, if G is Either, - * we collect all the Right values, etc. - */ - def unite[G[_], A](fga: F[G[A]])(implicit G: Foldable[G]): F[A] = - flatMap(fga) { ga => - G.foldLeft(ga, empty[A])((acc, a) => combineK(acc, pure(a))) - } - - /** Separate the inner foldable values into the "lefts" and "rights" */ - def separate[G[_, _], A, B](fgab: F[G[A, B]])(implicit G: Bifoldable[G]): (F[A], F[B]) = { - val as = flatMap(fgab)(gab => G.bifoldMap(gab)(pure, _ => empty[A])(algebra[A])) - val bs = flatMap(fgab)(gab => G.bifoldMap(gab)(_ => empty[B], pure)(algebra[B])) - (as, bs) - } -} diff --git a/core/src/main/scala/cats/MonadFilter.scala b/core/src/main/scala/cats/MonadFilter.scala deleted file mode 100644 index e2099a49e21..00000000000 --- a/core/src/main/scala/cats/MonadFilter.scala +++ /dev/null @@ -1,18 +0,0 @@ -package cats - -import simulacrum.typeclass - -/** - * a Monad equipped with an additional method which allows us to - * create an "empty" value for the Monad (for whatever "empty" makes - * sense for that particular monad). This is of particular interest to - * us since it allows us to add a `filter` method to a Monad, which is - * used when pattern matching or using guards in for comprehensions. - */ -@typeclass trait MonadFilter[F[_]] extends Monad[F] with FunctorFilter[F] { - - def empty[A]: F[A] - - override def mapFilter[A, B](fa: F[A])(f: A => Option[B]): F[B] = - flatMap(fa)(a => f(a).fold(empty[B])(pure)) -} diff --git a/core/src/main/scala/cats/MonadReader.scala b/core/src/main/scala/cats/MonadReader.scala deleted file mode 100644 index 3902892b87b..00000000000 --- a/core/src/main/scala/cats/MonadReader.scala +++ /dev/null @@ -1,17 +0,0 @@ -package cats - -/** A monad that has the ability to read from an environment. */ -trait MonadReader[F[_], R] extends Monad[F] { - /** Get the environment */ - def ask: F[R] - - /** Modify the environment */ - def local[A](f: R => R)(fa: F[A]): F[A] - - /** Retrieves a function of the environment */ - def reader[A](f: R => A): F[A] = map(ask)(f) -} - -object MonadReader { - def apply[F[_], R](implicit F: MonadReader[F, R]): MonadReader[F, R] = F -} diff --git a/core/src/main/scala/cats/MonadState.scala b/core/src/main/scala/cats/MonadState.scala deleted file mode 100644 index abc45d44886..00000000000 --- a/core/src/main/scala/cats/MonadState.scala +++ /dev/null @@ -1,52 +0,0 @@ -package cats - -/** A monad that can read, update, and pass along state (e.g. `StateT`). - * - * A common use case for `MonadState` is for syntax, especially when - * dealing with large monad transformer stacks. For instance: - * - * {{{ - * val M = MonadState[StateT[List, Int, ?], Int] - * import M._ - * - * for { - * g <- get - * _ <- set(g + 1) - * r <- inspect(_ * 100) - * } yield r - * }}} - */ -trait MonadState[F[_], S] extends Monad[F] { - - /** - * Embed a state action into the monad. - * - * Example: - * {{{ - * scala> import cats.MonadState - * scala> import cats.data.StateT - * scala> import cats.instances.list._ - * - * scala> val M = MonadState[StateT[List, Int, ?], Int] - * scala> import M._ - * - * scala> val st: StateT[List, Int, Int] = state(s => (s + 1, s * 100)) - * scala> st.run(1) - * res0: List[(Int, Int)] = List((2,100)) - * }}} - */ - def state[A](f: S => (S, A)): F[A] = - flatMap(get)(s => f(s) match { case (s, a) => map(set(s))(_ => a) }) - - def get: F[S] - - def set(s: S): F[Unit] - - def modify(f: S => S): F[Unit] = flatMap(get)(s => set(f(s))) - - def inspect[A](f: S => A): F[A] = map(get)(f) -} - -object MonadState { - def apply[F[_], S](implicit F: MonadState[F, S]): MonadState[F, S] = F -} diff --git a/core/src/main/scala/cats/MonadTrans.scala b/core/src/main/scala/cats/MonadTrans.scala deleted file mode 100644 index c3d116ef251..00000000000 --- a/core/src/main/scala/cats/MonadTrans.scala +++ /dev/null @@ -1,17 +0,0 @@ -package cats - -/** - * A type class which abstracts over the ability to lift an M[A] into a - * MonadTransformer - */ -trait MonadTrans[MT[_[_], _]] extends Any with Serializable { - - /** - * Lift a value of type M[A] into a monad transformer MT[M, A] - */ - def liftT[M[_]: Monad, A](ma: M[A]): MT[M, A] -} - -object MonadTrans { - def apply[MT[_[_], _]](implicit MT: MonadTrans[MT]): MonadTrans[MT] = MT -} diff --git a/core/src/main/scala/cats/MonadWriter.scala b/core/src/main/scala/cats/MonadWriter.scala deleted file mode 100644 index 5481e4cb965..00000000000 --- a/core/src/main/scala/cats/MonadWriter.scala +++ /dev/null @@ -1,28 +0,0 @@ -package cats - -/** A monad that support monoidal accumulation (e.g. logging List[String]) */ -trait MonadWriter[F[_], W] extends Monad[F] { - /** Lift a writer action into the effect */ - def writer[A](aw: (W, A)): F[A] - - /** Run the effect and pair the accumulator with the result */ - def listen[A](fa: F[A]): F[(W, A)] - - /** Apply the effectful function to the accumulator */ - def pass[A](fa: F[(W => W, A)]): F[A] - - /** Lift the log into the effect */ - def tell(w: W): F[Unit] = writer((w, ())) - - /** Pair the value with an inspection of the accumulator */ - def listens[A, B](fa: F[A])(f: W => B): F[(B, A)] = - map(listen(fa)) { case (w, a) => (f(w), a) } - - /** Modify the accumulator */ - def censor[A](fa: F[A])(f: W => W): F[A] = - flatMap(listen(fa)) { case (w, a) => writer((f(w), a)) } -} - -object MonadWriter { - def apply[F[_], W](implicit F: MonadWriter[F, W]): MonadWriter[F, W] = F -} diff --git a/core/src/main/scala/cats/Traverse.scala b/core/src/main/scala/cats/Traverse.scala index 4b6f86f534e..a8166c16604 100644 --- a/core/src/main/scala/cats/Traverse.scala +++ b/core/src/main/scala/cats/Traverse.scala @@ -92,12 +92,6 @@ import simulacrum.typeclass val G = Traverse[G] } - def composeFilter[G[_]: TraverseFilter]: TraverseFilter[λ[α => F[G[α]]]] = - new ComposedTraverseFilter[F, G] { - val F = self - val G = TraverseFilter[G] - } - override def map[A, B](fa: F[A])(f: A => B): F[B] = traverse[Id, A, B](fa)(f) diff --git a/core/src/main/scala/cats/TraverseFilter.scala b/core/src/main/scala/cats/TraverseFilter.scala deleted file mode 100644 index 9e6c1ebac63..00000000000 --- a/core/src/main/scala/cats/TraverseFilter.scala +++ /dev/null @@ -1,65 +0,0 @@ -package cats - -import simulacrum.typeclass - -/** - * `TraverseFilter`, also known as `Witherable`, represents list-like structures - * that can essentially have a [[traverse]] and a [[filter]] applied as a single - * combined operation ([[traverseFilter]]). - * - * Must obey the laws defined in cats.laws.TraverseFilterLaws. - * - * Based on Haskell's [[https://hackage.haskell.org/package/witherable-0.1.3.3/docs/Data-Witherable.html Data.Witherable]] - */ -@typeclass trait TraverseFilter[F[_]] extends Traverse[F] with FunctorFilter[F] { self => - - /** - * A combined [[traverse]] and [[filter]]. Filtering is handled via `Option` - * instead of `Boolean` such that the output type `B` can be different than - * the input type `A`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val m: Map[Int, String] = Map(1 -> "one", 3 -> "three") - * scala> val l: List[Int] = List(1, 2, 3, 4) - * scala> def asString(i: Int): Eval[Option[String]] = Now(m.get(i)) - * scala> val result: Eval[List[String]] = l.traverseFilter(asString) - * scala> result.value - * res0: List[String] = List(one, three) - * }}} - */ - def traverseFilter[G[_]: Applicative, A, B](fa: F[A])(f: A => G[Option[B]]): G[F[B]] - - override def mapFilter[A, B](fa: F[A])(f: A => Option[B]): F[B] = - traverseFilter[Id, A, B](fa)(f) - - /** - * - * Filter values inside a `G` context. - * - * This is a generalized version of Haskell's [[http://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Monad.html#v:filterM filterM]]. - * [[http://stackoverflow.com/questions/28872396/haskells-filterm-with-filterm-x-true-false-1-2-3 This StackOverflow question]] about `filterM` may be helpful in understanding how it behaves. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l: List[Int] = List(1, 2, 3, 4) - * scala> def odd(i: Int): Eval[Boolean] = Now(i % 2 == 1) - * scala> val res: Eval[List[Int]] = l.filterA(odd) - * scala> res.value - * res0: List[Int] = List(1, 3) - * - * scala> List(1, 2, 3).filterA(_ => List(true, false)) - * res1: List[List[Int]] = List(List(1, 2, 3), List(1, 2), List(1, 3), List(1), List(2, 3), List(2), List(3), List()) - * }}} - */ - def filterA[G[_], A](fa: F[A])(f: A => G[Boolean])(implicit G: Applicative[G]): G[F[A]] = - traverseFilter(fa)(a => G.map(f(a))(if (_) Some(a) else None)) - - override def filter[A](fa: F[A])(f: A => Boolean): F[A] = - filterA[Id, A](fa)(f) - - override def traverse[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Applicative[G]): G[F[B]] = - traverseFilter(fa)(a => G.map(f(a))(Some(_))) -} diff --git a/core/src/main/scala/cats/data/Const.scala b/core/src/main/scala/cats/data/Const.scala index 6d326a3366d..6fe898c56cf 100644 --- a/core/src/main/scala/cats/data/Const.scala +++ b/core/src/main/scala/cats/data/Const.scala @@ -17,9 +17,6 @@ final case class Const[A, B](getConst: A) { def combine(that: Const[A, B])(implicit A: Semigroup[A]): Const[A, B] = Const(A.combine(getConst, that.getConst)) - def traverseFilter[F[_], C](f: B => F[Option[C]])(implicit F: Applicative[F]): F[Const[A, C]] = - F.pure(retag[C]) - def traverse[F[_], C](f: B => F[C])(implicit F: Applicative[F]): F[Const[A, C]] = F.pure(retag[C]) @@ -73,10 +70,7 @@ private[data] sealed abstract class ConstInstances extends ConstInstances0 { fa.retag[B] } - implicit def catsDataTraverseFilterForConst[C]: TraverseFilter[Const[C, ?]] = new TraverseFilter[Const[C, ?]] { - def traverseFilter[G[_]: Applicative, A, B](fa: Const[C, A])(f: A => G[Option[B]]): G[Const[C, B]] = - fa.traverseFilter(f) - + implicit def catsDataTraverseForConst[C]: Traverse[Const[C, ?]] = new Traverse[Const[C, ?]] { def foldLeft[A, B](fa: Const[C, A], b: B)(f: (B, A) => B): B = b def foldRight[A, B](fa: Const[C, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = lb @@ -85,7 +79,7 @@ private[data] sealed abstract class ConstInstances extends ConstInstances0 { override def get[A](fa: Const[C, A])(idx: Long): Option[A] = None - override def traverse[G[_]: Applicative, A, B](fa: Const[C, A])(f: A => G[B]): G[Const[C, B]] = + def traverse[G[_]: Applicative, A, B](fa: Const[C, A])(f: A => G[B]): G[Const[C, B]] = fa.traverse(f) } diff --git a/core/src/main/scala/cats/data/EitherK.scala b/core/src/main/scala/cats/data/EitherK.scala index 8c6d5e3cc30..37f6d13854f 100644 --- a/core/src/main/scala/cats/data/EitherK.scala +++ b/core/src/main/scala/cats/data/EitherK.scala @@ -5,9 +5,9 @@ import cats.arrow.FunctionK import cats.functor.Contravariant import cats.syntax.either._ -/** `F` on the left and `G` on the right of [[scala.util.Either]]. +/** `F` on the left and `G` on the right of `scala.util.Either`. * - * @param run The underlying [[scala.util.Either]]. + * @param run The underlying `scala.util.Either`. */ final case class EitherK[F[_], G[_], A](run: Either[F[A], G[A]]) { diff --git a/core/src/main/scala/cats/data/EitherT.scala b/core/src/main/scala/cats/data/EitherT.scala index b95c67df0e5..a0ad4680ba6 100644 --- a/core/src/main/scala/cats/data/EitherT.scala +++ b/core/src/main/scala/cats/data/EitherT.scala @@ -63,8 +63,8 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def to[G[_]](implicit F: Functor[F], G: Alternative[G]): F[G[B]] = F.map(value)(_.to[G]) - def collectRight(implicit F: MonadCombine[F]): F[B] = - F.flatMap(value)(_.to[F]) + def collectRight(implicit FA: Alternative[F], FM: Monad[F]): F[B] = + FM.flatMap(value)(_.to[F]) def bimap[C, D](fa: A => C, fb: B => D)(implicit F: Functor[F]): EitherT[F, C, D] = EitherT(F.map(value)(_.bimap(fa, fb))) @@ -446,12 +446,6 @@ private[data] abstract class EitherTInstances extends EitherTInstances1 { val F0: Traverse[F] = F } - implicit def catsDataMonadTransForEitherT[E]: MonadTrans[EitherT[?[_], E, ?]] = - new MonadTrans[EitherT[?[_], E, ?]] { - def liftT[M[_]: Monad, A](ma: M[A]): EitherT[M, E, A] = - EitherT.liftT(ma) - } - implicit def catsMonoidForEitherT[F[_], L, A](implicit F: Monoid[F[Either[L, A]]]): Monoid[EitherT[F, L, A]] = new EitherTMonoid[F, L, A] { implicit val F0 = F } diff --git a/core/src/main/scala/cats/data/IdT.scala b/core/src/main/scala/cats/data/IdT.scala index 607b91c1074..c1d013a6a49 100644 --- a/core/src/main/scala/cats/data/IdT.scala +++ b/core/src/main/scala/cats/data/IdT.scala @@ -161,8 +161,4 @@ private[data] sealed abstract class IdTInstances extends IdTInstances0 { implicit def catsDataShowForIdT[F[_], A](implicit F: Show[F[A]]): Show[IdT[F, A]] = functor.Contravariant[Show].contramap(F)(_.value) - implicit def catsDataMonadTransForIdT: MonadTrans[IdT] = - new MonadTrans[IdT] { - def liftT[M[_]: Monad, A](ma: M[A]): IdT[M, A] = IdT(ma) - } } diff --git a/core/src/main/scala/cats/data/Ior.scala b/core/src/main/scala/cats/data/Ior.scala index 96a15bf2599..a712276caf8 100644 --- a/core/src/main/scala/cats/data/Ior.scala +++ b/core/src/main/scala/cats/data/Ior.scala @@ -13,14 +13,14 @@ import scala.annotation.tailrec * - `[[Ior.Right Right]][B]` * - `[[Ior.Both Both]][A, B]` * - * `A [[Ior]] B` is similar to `Either[A, B]`, except that it can represent the simultaneous presence of + * `A [[Ior]] B` is similar to `scala.util.Either[A, B]`, except that it can represent the simultaneous presence of * an `A` and a `B`. It is right-biased so methods such as `map` and `flatMap` operate on the * `B` value. Some methods, like `flatMap`, handle the presence of two [[Ior.Both Both]] values using a * `[[Semigroup]][A]`, while other methods, like [[toEither]], ignore the `A` value in a [[Ior.Both Both]]. * * `A [[Ior]] B` is isomorphic to `Either[Either[A, B], (A, B)]`, but provides methods biased toward `B` * values, regardless of whether the `B` values appear in a [[Ior.Right Right]] or a [[Ior.Both Both]]. - * The isomorphic [[scala.util.Either]] form can be accessed via the [[unwrap]] method. + * The isomorphic `scala.util.Either` form can be accessed via the [[unwrap]] method. */ sealed abstract class Ior[+A, +B] extends Product with Serializable { diff --git a/core/src/main/scala/cats/data/Kleisli.scala b/core/src/main/scala/cats/data/Kleisli.scala index bec95e659f9..8bc3719945a 100644 --- a/core/src/main/scala/cats/data/Kleisli.scala +++ b/core/src/main/scala/cats/data/Kleisli.scala @@ -85,17 +85,23 @@ private[data] sealed abstract class KleisliInstances extends KleisliInstances0 { new KleisliMonad[F, A] with CommutativeMonad[Kleisli[F, A, ?]] { implicit def F: Monad[F] = F0 } + + implicit def catsDataArrowForKleisli[F[_]](implicit M: Monad[F]): Arrow[Kleisli[F, ?, ?]] = + new KleisliArrow[F] { + def F: Monad[F] = M + } + } private[data] sealed abstract class KleisliInstances0 extends KleisliInstances1 { implicit def catsDataMonoidForKleisli[F[_], A, B](implicit FB0: Monoid[F[B]]): Monoid[Kleisli[F, A, B]] = new KleisliMonoid[F, A, B] { def FB: Monoid[F[B]] = FB0 } - implicit def catsDataMonoidKForKleisli[F[_]](implicit M: Monad[F]): MonoidK[λ[α => Kleisli[F, α, α]]] = - Category[Kleisli[F, ?, ?]].algebraK + implicit def catsDataMonadErrorForKleisli[F[_], A, E](implicit ME: MonadError[F, E]): MonadError[Kleisli[F, A, ?], E] = + new KleisliMonadError[F, A, E] { def F: MonadError[F, E] = ME } - implicit val catsDataMonoidKForKleisliId: MonoidK[λ[α => Kleisli[Id, α, α]]] = - catsDataMonoidKForKleisli[Id] + implicit def catsDataMonadForKleisliId[A]: Monad[Kleisli[Id, A, ?]] = + catsDataMonadForKleisli[Id, A] implicit def catsDataCommutativeArrowForKleisli[F[_]](implicit M: CommutativeMonad[F]): CommutativeArrow[Kleisli[F, ?, ?]] = new KleisliCommutativeArrow[F] {def F: CommutativeMonad[F] = M } @@ -103,38 +109,34 @@ private[data] sealed abstract class KleisliInstances0 extends KleisliInstances1 implicit val catsDataCommutativeArrowForKleisliId: CommutativeArrow[Kleisli[Id, ?, ?]] = catsDataCommutativeArrowForKleisli[Id] - implicit def catsDataMonadReaderForKleisliId[A]: MonadReader[Kleisli[Id, A, ?], A] = - catsDataMonadReaderForKleisli[Id, A] - implicit def catsDataContravariantForKleisli[F[_], C]: Contravariant[Kleisli[F, ?, C]] = new Contravariant[Kleisli[F, ?, C]] { override def contramap[A, B](fa: Kleisli[F, A, C])(f: B => A): Kleisli[F, B, C] = fa.local(f) } - implicit def catsDataMonadTransForKleisli[A]: MonadTrans[Kleisli[?[_], A, ?]] = - new MonadTrans[Kleisli[?[_], A, ?]] { - def liftT[M[_]: Monad, B](ma: M[B]): Kleisli[M, A, B] = Kleisli.lift(ma) - } - - implicit def catsDataApplicativeErrorForKleisli[F[_], A, E](implicit AE: ApplicativeError[F, E]): ApplicativeError[Kleisli[F, A, ?], E] = - new KleisliApplicativeError[F, A, E] { def F: ApplicativeError[F, E] = AE } } private[data] sealed abstract class KleisliInstances1 extends KleisliInstances2 { - implicit def catsDataArrowForKleisli[F[_]](implicit M: Monad[F]): Arrow[Kleisli[F, ?, ?]] = - new KleisliArrow[F] { def F: Monad[F] = M } - - implicit def catsDataMonadErrorForKleisli[F[_], A, E](implicit ME: MonadError[F, E]): MonadError[Kleisli[F, A, ?], E] = - new KleisliMonadError[F, A, E] { def F: MonadError[F, E] = ME } + implicit def catsDataMonadForKleisli[F[_], A](implicit M: Monad[F]): Monad[Kleisli[F, A, ?]] = + new KleisliMonad[F, A] { def F: Monad[F] = M } } private[data] sealed abstract class KleisliInstances2 extends KleisliInstances3 { - implicit def catsDataMonadReaderForKleisli[F[_], A](implicit M: Monad[F]): MonadReader[Kleisli[F, A, ?], A] = - new KleisliMonadReader[F, A] { def F: Monad[F] = M } + implicit def catsDataAlternativeForKleisli[F[_], A](implicit F0: Alternative[F]): Alternative[Kleisli[F, A, ?]] = + new KleisliAlternative[F, A] { def F: Alternative[F] = F0 } } private[data] sealed abstract class KleisliInstances3 extends KleisliInstances4 { + implicit def catsDataMonoidKForKleisli[F[_]](implicit M: Monad[F]): MonoidK[λ[α => Kleisli[F, α, α]]] = + Category[Kleisli[F, ?, ?]].algebraK + + implicit val catsDataMonoidKForKleisliId: MonoidK[λ[α => Kleisli[Id, α, α]]] = + catsDataMonoidKForKleisli[Id] + + implicit def catsDataFlatMapForKleisli[F[_], A](implicit FM: FlatMap[F]): FlatMap[Kleisli[F, A, ?]] = + new KleisliFlatMap[F, A] { def F: FlatMap[F] = FM } + implicit def catsDataChoiceForKleisli[F[_]](implicit M: Monad[F]): Choice[Kleisli[F, ?, ?]] = new KleisliChoice[F] { def F: Monad[F] = M } @@ -147,27 +149,29 @@ private[data] sealed abstract class KleisliInstances3 extends KleisliInstances4 implicit def catsDataStrongForKleisli[F[_]](implicit F0: Functor[F]): Strong[Kleisli[F, ?, ?]] = new KleisliStrong[F] { def F: Functor[F] = F0 } - implicit def catsDataFlatMapForKleisli[F[_], A](implicit FM: FlatMap[F]): FlatMap[Kleisli[F, A, ?]] = - new KleisliFlatMap[F, A] { def F: FlatMap[F] = FM } - implicit def catsDataSemigroupForKleisli[F[_], A, B](implicit FB0: Semigroup[F[B]]): Semigroup[Kleisli[F, A, B]] = new KleisliSemigroup[F, A, B] { def FB: Semigroup[F[B]] = FB0 } +} +private[data] sealed abstract class KleisliInstances4 extends KleisliInstances5 { implicit def catsDataSemigroupKForKleisli[F[_]](implicit FM: FlatMap[F]): SemigroupK[λ[α => Kleisli[F, α, α]]] = Compose[Kleisli[F, ?, ?]].algebraK + + implicit def catsDataApplicativeErrorForKleisli[F[_], E, A](implicit F0: ApplicativeError[F, E]): ApplicativeError[Kleisli[F, A, ?], E] = + new KleisliApplicativeError[F, A, E] { def F: ApplicativeError[F, E] = F0 } } -private[data] sealed abstract class KleisliInstances4 extends KleisliInstances5 { +private[data] sealed abstract class KleisliInstances5 extends KleisliInstances6 { implicit def catsDataApplicativeForKleisli[F[_], A](implicit A: Applicative[F]): Applicative[Kleisli[F, A, ?]] = new KleisliApplicative[F, A] { def F: Applicative[F] = A } } -private[data] sealed abstract class KleisliInstances5 extends KleisliInstances6 { +private[data] sealed abstract class KleisliInstances6 extends KleisliInstances7 { implicit def catsDataApplyForKleisli[F[_], A](implicit A: Apply[F]): Apply[Kleisli[F, A, ?]] = new KleisliApply[F, A] { def F: Apply[F] = A } } -private[data] sealed abstract class KleisliInstances6 { +private[data] sealed abstract class KleisliInstances7 { implicit def catsDataFunctorForKleisli[F[_], A](implicit F0: Functor[F]): Functor[Kleisli[F, A, ?]] = new KleisliFunctor[F, A] { def F: Functor[F] = F0 } } @@ -236,7 +240,7 @@ private trait KleisliMonoid[F[_], A, B] extends Monoid[Kleisli[F, A, B]] with Kl override def empty: Kleisli[F, A, B] = Kleisli[F, A, B](_ => FB.empty) } -private trait KleisliMonadError[F[_], A, E] extends MonadError[Kleisli[F, A, ?], E] with KleisliApplicativeError[F, A, E] with KleisliMonadReader[F, A] { +private trait KleisliMonadError[F[_], A, E] extends MonadError[Kleisli[F, A, ?], E] with KleisliApplicativeError[F, A, E] with KleisliMonad[F, A] { def F: MonadError[F, E] } @@ -252,14 +256,6 @@ private trait KleisliApplicativeError[F[_], A, E] extends ApplicativeError[Kleis } } -private trait KleisliMonadReader[F[_], A] extends MonadReader[Kleisli[F, A, ?], A] with KleisliMonad[F, A] { - implicit def F: Monad[F] - - val ask: Kleisli[F, A, A] = Kleisli.ask[F, A] - - def local[B](f: A => A)(fa: Kleisli[F, A, B]): Kleisli[F, A, B] = Kleisli.local(f)(fa) -} - private trait KleisliMonad[F[_], A] extends Monad[Kleisli[F, A, ?]] with KleisliFlatMap[F, A] with KleisliApplicative[F, A] { implicit def F: Monad[F] } @@ -281,6 +277,16 @@ private trait KleisliApplicative[F[_], A] extends Applicative[Kleisli[F, A, ?]] Kleisli.pure[F, A, B](x) } +private trait KleisliAlternative[F[_], A] extends Alternative[Kleisli[F, A, ?]] with KleisliApplicative[F, A] { + implicit def F: Alternative[F] + + def empty[X]: Kleisli[F, A, X] = + Kleisli.lift(F.empty[X]) + + def combineK[X](x: ReaderT[F, A, X], y: ReaderT[F, A, X]): ReaderT[F, A, X] = + ReaderT[F, A, X](a => F.combineK(x(a), y(a))) +} + private trait KleisliApply[F[_], A] extends Apply[Kleisli[F, A, ?]] with KleisliFunctor[F, A] { implicit def F: Apply[F] diff --git a/core/src/main/scala/cats/data/Nested.scala b/core/src/main/scala/cats/data/Nested.scala index d8d6fc54df3..9540772f296 100644 --- a/core/src/main/scala/cats/data/Nested.scala +++ b/core/src/main/scala/cats/data/Nested.scala @@ -31,11 +31,6 @@ private[data] sealed abstract class NestedInstances extends NestedInstances0 { implicit def catsDataEqForNested[F[_], G[_], A](implicit FGA: Eq[F[G[A]]]): Eq[Nested[F, G, A]] = FGA.on(_.value) - implicit def catsDataTraverseFilterForNested[F[_]: Traverse, G[_]: TraverseFilter]: TraverseFilter[Nested[F, G, ?]] = - new NestedTraverseFilter[F, G] { - val FG: TraverseFilter[λ[α => F[G[α]]]] = Traverse[F].composeFilter[G] - } - implicit def catsDataNonEmptyTraverseForNested[F[_]: NonEmptyTraverse, G[_]: NonEmptyTraverse]: NonEmptyTraverse[Nested[F, G, ?]] = new NestedNonEmptyTraverse[F, G] { val FG: NonEmptyTraverse[λ[α => F[G[α]]]] = NonEmptyTraverse[F].compose[G] @@ -43,7 +38,6 @@ private[data] sealed abstract class NestedInstances extends NestedInstances0 { } private[data] sealed abstract class NestedInstances0 extends NestedInstances1 { - implicit def catsDataTraverseForNested[F[_]: Traverse, G[_]: Traverse]: Traverse[Nested[F, G, ?]] = new NestedTraverse[F, G] { val FG: Traverse[λ[α => F[G[α]]]] = Traverse[F].compose[G] @@ -131,14 +125,7 @@ private[data] sealed abstract class NestedInstances8 extends NestedInstances9 { } } -private[data] sealed abstract class NestedInstances9 extends NestedInstances10 { - implicit def catsDataFunctorFilterForNested[F[_]: Functor, G[_]: FunctorFilter]: FunctorFilter[Nested[F, G, ?]] = - new NestedFunctorFilter[F, G] { - val FG: FunctorFilter[λ[α => F[G[α]]]] = Functor[F].composeFilter[G] - } -} - -private[data] sealed abstract class NestedInstances10 { +private[data] sealed abstract class NestedInstances9 { implicit def catsDataInvariantForNestedContravariant[F[_]: Invariant, G[_]: Contravariant]: Invariant[Nested[F, G, ?]] = new NestedInvariant[F, G] { val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].composeContravariant[G] @@ -159,26 +146,6 @@ private[data] trait NestedFunctor[F[_], G[_]] extends Functor[Nested[F, G, ?]] w Nested(FG.map(fga.value)(f)) } -private[data] trait NestedFunctorFilter[F[_], G[_]] extends FunctorFilter[Nested[F, G, ?]] with NestedFunctor[F, G] { - override def FG: FunctorFilter[λ[α => F[G[α]]]] - - override def mapFilter[A, B](fga: Nested[F, G, A])(f: A => Option[B]): Nested[F, G, B] = - Nested(FG.mapFilter(fga.value)(f)) - - override def collect[A, B](fga: Nested[F, G, A])(f: PartialFunction[A, B]): Nested[F, G, B] = - Nested(FG.collect(fga.value)(f)) - - override def filter[A](fga: Nested[F, G, A])(f: A => Boolean): Nested[F, G, A] = - Nested(FG.filter(fga.value)(f)) -} - -private[data] trait NestedTraverseFilter[F[_], G[_]] extends TraverseFilter[Nested[F, G, ?]] with NestedFunctorFilter[F, G] with NestedTraverse[F, G] { - override def FG: TraverseFilter[λ[α => F[G[α]]]] - - override def traverseFilter[H[_]: Applicative, A, B](fga: Nested[F, G, A])(f: A => H[Option[B]]): H[Nested[F, G, B]] = - Applicative[H].map(FG.traverseFilter(fga.value)(f))(Nested(_)) -} - private[data] trait NestedApply[F[_], G[_]] extends Apply[Nested[F, G, ?]] with NestedFunctor[F, G] { override def FG: Apply[λ[α => F[G[α]]]] diff --git a/core/src/main/scala/cats/data/OneAnd.scala b/core/src/main/scala/cats/data/OneAnd.scala index 9d85b8d8e54..43963d461ad 100644 --- a/core/src/main/scala/cats/data/OneAnd.scala +++ b/core/src/main/scala/cats/data/OneAnd.scala @@ -25,9 +25,9 @@ final case class OneAnd[F[_], A](head: A, tail: F[A]) { /** * remove elements not matching the predicate */ - def filter(f: A => Boolean)(implicit F: MonadCombine[F]): F[A] = { - val rest = F.filter(tail)(f) - if (f(head)) F.combineK(F.pure(head), rest) else rest + def filter(f: A => Boolean)(implicit FA: Alternative[F], FM: Monad[F]): F[A] = { + val rest = FM.flatMap(tail)(a => if (f(a)) FM.pure(a) else FA.empty[A]) + if (f(head)) FA.combineK(FM.pure(head), rest) else rest } /** @@ -127,27 +127,27 @@ private[data] sealed trait OneAndInstances extends OneAndLowPriority3 { override def size[A](fa: OneAnd[F, A]): Long = 1 + F.size(fa.tail) } - implicit def catsDataMonadForOneAnd[F[_]](implicit monad: MonadCombine[F]): Monad[OneAnd[F, ?]] = + implicit def catsDataMonadForOneAnd[F[_]](implicit monad: Monad[F], alternative: Alternative[F]): Monad[OneAnd[F, ?]] = new Monad[OneAnd[F, ?]] { override def map[A, B](fa: OneAnd[F, A])(f: A => B): OneAnd[F, B] = - fa map f + fa.map(f)(monad) def pure[A](x: A): OneAnd[F, A] = - OneAnd(x, monad.empty) + OneAnd(x, alternative.empty) def flatMap[A, B](fa: OneAnd[F, A])(f: A => OneAnd[F, B]): OneAnd[F, B] = { val end = monad.flatMap(fa.tail) { a => val fa = f(a) - monad.combineK(monad.pure(fa.head), fa.tail) + alternative.combineK(monad.pure(fa.head), fa.tail) } val fst = f(fa.head) - OneAnd(fst.head, monad.combineK(fst.tail, end)) + OneAnd(fst.head, alternative.combineK(fst.tail, end)) } def tailRecM[A, B](a: A)(fn: A => OneAnd[F, Either[A, B]]): OneAnd[F, B] = { def stepF(a: A): F[Either[A, B]] = { val oneAnd = fn(a) - monad.combineK(monad.pure(oneAnd.head), oneAnd.tail) + alternative.combineK(monad.pure(oneAnd.head), oneAnd.tail) } def toFB(in: Either[A, B]): F[B] = in match { case Right(b) => monad.pure(b) @@ -157,9 +157,9 @@ private[data] sealed trait OneAndInstances extends OneAndLowPriority3 { // This could probably be in SemigroupK to perform well @tailrec def combineAll(items: List[F[B]]): F[B] = items match { - case Nil => monad.empty + case Nil => alternative.empty case h :: Nil => h - case h1 :: h2 :: tail => combineAll(monad.combineK(h1, h2) :: tail) + case h1 :: h2 :: tail => combineAll(alternative.combineK(h1, h2) :: tail) } @tailrec @@ -226,7 +226,7 @@ private[data] trait OneAndLowPriority2 extends OneAndLowPriority1 { } private[data] trait OneAndLowPriority3 extends OneAndLowPriority2 { - implicit def catsDataNonEmptyTraverseForOneAnd[F[_]](implicit F: Traverse[F], F2: MonadCombine[F]): NonEmptyTraverse[OneAnd[F, ?]] = + implicit def catsDataNonEmptyTraverseForOneAnd[F[_]](implicit F: Traverse[F], F2: Alternative[F]): NonEmptyTraverse[OneAnd[F, ?]] = new NonEmptyReducible[OneAnd[F, ?], F] with NonEmptyTraverse[OneAnd[F, ?]] { def nonEmptyTraverse[G[_], A, B](fa: OneAnd[F, A])(f: (A) => G[B])(implicit G: Apply[G]): G[OneAnd[F, B]] = { import cats.syntax.apply._ diff --git a/core/src/main/scala/cats/data/OptionT.scala b/core/src/main/scala/cats/data/OptionT.scala index f75156ccdcf..dfe86656756 100644 --- a/core/src/main/scala/cats/data/OptionT.scala +++ b/core/src/main/scala/cats/data/OptionT.scala @@ -103,9 +103,6 @@ final case class OptionT[F[_], A](value: F[Option[A]]) { def ===(that: OptionT[F, A])(implicit eq: Eq[F[Option[A]]]): Boolean = eq.eqv(value, that.value) - def traverseFilter[G[_], B](f: A => G[Option[B]])(implicit F: Traverse[F], G: Applicative[G]): G[OptionT[F, B]] = - G.map(F.composeFilter(optionInstance).traverseFilter(value)(f))(OptionT.apply) - def traverse[G[_], B](f: A => G[B])(implicit F: Traverse[F], G: Applicative[G]): G[OptionT[F, B]] = G.map(F.compose(optionInstance).traverse(value)(f))(OptionT.apply) @@ -230,11 +227,6 @@ private[data] sealed trait OptionTInstances0 extends OptionTInstances1 { } private[data] sealed trait OptionTInstances1 extends OptionTInstances2 { - // do NOT change this to val! I know it looks like it should work, and really I agree, but it doesn't (for... reasons) - implicit def catsDataMonadTransForOptionT: MonadTrans[OptionT] = - new MonadTrans[OptionT] { - def liftT[M[_]: Monad, A](ma: M[A]): OptionT[M, A] = OptionT.liftF(ma) - } implicit def catsDataMonoidKForOptionT[F[_]](implicit F0: Monad[F]): MonoidK[OptionT[F, ?]] = new OptionTMonoidK[F] { implicit val F = F0 } @@ -244,22 +236,19 @@ private[data] sealed trait OptionTInstances1 extends OptionTInstances2 { } private[data] sealed trait OptionTInstances2 extends OptionTInstances3 { - implicit def catsDataTraverseForOptionT[F[_]](implicit F0: Traverse[F]): TraverseFilter[OptionT[F, ?]] = - new OptionTTraverseFilter[F] { implicit val F = F0 } + implicit def catsDataTraverseForOptionT[F[_]](implicit F0: Traverse[F]): Traverse[OptionT[F, ?]] = + new OptionTTraverse[F] { implicit val F = F0 } } private[data] sealed trait OptionTInstances3 { - implicit def catsDataFunctorFilterForOptionT[F[_]](implicit F0: Functor[F]): FunctorFilter[OptionT[F, ?]] = + implicit def catsDataFunctorForOptionT[F[_]](implicit F0: Functor[F]): Functor[OptionT[F, ?]] = new OptionTFunctor[F] { implicit val F = F0 } } -private[data] trait OptionTFunctor[F[_]] extends FunctorFilter[OptionT[F, ?]] { +private[data] trait OptionTFunctor[F[_]] extends Functor[OptionT[F, ?]] { implicit def F: Functor[F] override def map[A, B](fa: OptionT[F, A])(f: A => B): OptionT[F, B] = fa.map(f) - - override def mapFilter[A, B](fa: OptionT[F, A])(f: A => Option[B]): OptionT[F, B] = - fa.mapFilter(f) } private[data] trait OptionTMonad[F[_]] extends Monad[OptionT[F, ?]] { @@ -297,13 +286,10 @@ private[data] trait OptionTFoldable[F[_]] extends Foldable[OptionT[F, ?]] { fa.foldRight(lb)(f) } -private[data] sealed trait OptionTTraverseFilter[F[_]] extends TraverseFilter[OptionT[F, ?]] with OptionTFoldable[F] { +private[data] sealed trait OptionTTraverse[F[_]] extends Traverse[OptionT[F, ?]] with OptionTFoldable[F] { implicit def F: Traverse[F] - def traverseFilter[G[_]: Applicative, A, B](fa: OptionT[F, A])(f: A => G[Option[B]]): G[OptionT[F, B]] = - fa traverseFilter f - - override def traverse[G[_]: Applicative, A, B](fa: OptionT[F, A])(f: A => G[B]): G[OptionT[F, B]] = + def traverse[G[_]: Applicative, A, B](fa: OptionT[F, A])(f: A => G[B]): G[OptionT[F, B]] = fa traverse f } diff --git a/core/src/main/scala/cats/data/ReaderWriterStateT.scala b/core/src/main/scala/cats/data/ReaderWriterStateT.scala index 9f9a655e953..fdd352bfb82 100644 --- a/core/src/main/scala/cats/data/ReaderWriterStateT.scala +++ b/core/src/main/scala/cats/data/ReaderWriterStateT.scala @@ -319,19 +319,6 @@ private[data] abstract class RWSFunctions { } private[data] sealed trait RWSTInstances extends RWSTInstances1 { - implicit def catsDataMonadStateForRWST[F[_], E, L, S]( - implicit F0: Monad[F], L0: Monoid[L]): MonadState[ReaderWriterStateT[F, E, L, S, ?], S] = - new RWSTMonadState[F, E, L, S] { - implicit def F: Monad[F] = F0 - implicit def L: Monoid[L] = L0 - } - - implicit def catsDataMonadTransForRWST[E, L, S]( - implicit L0: Monoid[L]): MonadTrans[ReaderWriterStateT[?[_], E, L, S, ?]] = - new RWSTMonadTrans[E, L, S] { - implicit def L: Monoid[L] = L0 - } - implicit def catsDataProfunctorForRWST[F[_], L, S](implicit F0: Functor[F]): Profunctor[ReaderWriterStateT[F, ?, L, S, ?]] = new RWSTProfunctor[F, L, S] { implicit def F: Functor[F] = F0 @@ -341,60 +328,40 @@ private[data] sealed trait RWSTInstances extends RWSTInstances1 { new RWSTContravariant[F, L, S, A] { implicit def F: Functor[F] = F0 } -} -private[data] sealed trait RWSTInstances1 extends RWSTInstances2 { - implicit def catsDataMonadCombineForRWST[F[_], E, L, S]( - implicit F0: MonadCombine[F], L0: Monoid[L]): MonadCombine[ReaderWriterStateT[F, E, L, S, ?]] = - new RWSTMonadCombine[F, E, L, S] { - implicit def F: MonadCombine[F] = F0 - implicit def L: Monoid[L] = L0 - } -} - -private[data] sealed trait RWSTInstances2 extends RWSTInstances3 { - implicit def catsDataMonadErrorForRWST[F[_], E, L, S, R]( - implicit F0: MonadError[F, R], L0: Monoid[L]): MonadError[ReaderWriterStateT[F, E, L, S, ?], R] = + implicit def catsDataMonadErrorForRWST[F[_], E, L, S, R](implicit F0: MonadError[F, R], L0: Monoid[L]): MonadError[ReaderWriterStateT[F, E, L, S, ?], R] = new RWSTMonadError[F, E, L, S, R] { implicit def F: MonadError[F, R] = F0 implicit def L: Monoid[L] = L0 } - implicit def catsDataSemigroupKForRWST[F[_], E, L, S]( - implicit F0: Monad[F], G0: SemigroupK[F]): SemigroupK[ReaderWriterStateT[F, E, L, S, ?]] = - new RWSTSemigroupK[F, E, L, S] { - implicit def F: Monad[F] = F0 - implicit def G: SemigroupK[F] = G0 - } } -private[data] sealed trait RWSTInstances3 extends RWSTInstances4 { - implicit def catsDataMonadReaderForRWST[F[_], E, L, S]( - implicit F0: Monad[F], L0: Monoid[L]): MonadReader[ReaderWriterStateT[F, E, L, S, ?], E] = - new RWSTMonadReader[F, E, L, S] { +private[data] sealed trait RWSTInstances1 extends RWSTInstances2 { + implicit def catsDataMonadForRWST[F[_], E, L, S](implicit F0: Monad[F], L0: Monoid[L]): Monad[ReaderWriterStateT[F, E, L, S, ?]] = + new RWSTMonad[F, E, L, S] { implicit def F: Monad[F] = F0 implicit def L: Monoid[L] = L0 } } -private[data] sealed trait RWSTInstances4 extends RWSTInstances5 { - implicit def catsDataMonadWriterForRWST[F[_], E, L, S]( - implicit F0: Monad[F], L0: Monoid[L]): MonadWriter[ReaderWriterStateT[F, E, L, S, ?], L] = - new RWSTMonadWriter[F, E, L, S] { - implicit def F: Monad[F] = F0 +private[data] sealed trait RWSTInstances2 extends RWSTInstances3 { + implicit def catsDataAlternativeForRWST[F[_], E, L, S]( + implicit FM: Monad[F], FA: Alternative[F], L0: Monoid[L]): Alternative[ReaderWriterStateT[F, E, L, S, ?]] = + new RWSTAlternative[F, E, L, S] { + implicit def G: Alternative[F] = FA + implicit def F: Monad[F] = FM implicit def L: Monoid[L] = L0 } } -private[data] sealed trait RWSTInstances5 extends RWSTInstances6 { - implicit def catsDataMonadForRWST[F[_], E, L, S](implicit F0: Monad[F], L0: Monoid[L]): Monad[ReaderWriterStateT[F, E, L, S, ?]] = - new RWSTMonad[F, E, L, S] { +private[data] sealed trait RWSTInstances3 { + implicit def catsDataSemigroupKForRWST[F[_], E, L, S]( + implicit F0: Monad[F], G0: SemigroupK[F]): SemigroupK[ReaderWriterStateT[F, E, L, S, ?]] = + new RWSTSemigroupK[F, E, L, S] { implicit def F: Monad[F] = F0 - implicit def L: Monoid[L] = L0 + implicit def G: SemigroupK[F] = G0 } -} - -private[data] sealed trait RWSTInstances6 { implicit def catsDataFunctorForRWST[F[_], E, L, S](implicit F0: Functor[F]): Functor[ReaderWriterStateT[F, E, L, S, ?]] = new RWSTFunctor[F, E, L, S] { implicit def F: Functor[F] = F0 @@ -415,7 +382,6 @@ private[data] sealed trait RWSTContravariant[F[_], L, S, T] extends Contravarian fa.contramap(f) } - private[data] sealed trait RWSTProfunctor[F[_], L, S] extends Profunctor[ReaderWriterStateT[F, ?, L, S, ?]] { implicit def F: Functor[F] @@ -443,20 +409,6 @@ private[data] sealed trait RWSTMonad[F[_], E, L, S] extends Monad[ReaderWriterSt } } -private[data] sealed trait RWSTMonadState[F[_], E, L, S] - extends MonadState[ReaderWriterStateT[F, E, L, S, ?], S] with RWSTMonad[F, E, L, S] { - - lazy val get: ReaderWriterStateT[F, E, L, S, S] = ReaderWriterStateT.get - - def set(s: S): ReaderWriterStateT[F, E, L, S, Unit] = ReaderWriterStateT.set(s) -} - -private[data] sealed trait RWSTMonadTrans[E, L, S] extends MonadTrans[ReaderWriterStateT[?[_], E, L, S, ?]] { - implicit def L: Monoid[L] - def liftT[M[_]: Monad, A](ma: M[A]): ReaderWriterStateT[M, E, L, S, A] = - ReaderWriterStateT.lift(ma) -} - private[data] sealed trait RWSTSemigroupK[F[_], E, L, S] extends SemigroupK[ReaderWriterStateT[F, E, L, S, ?]] { implicit def F: Monad[F] implicit def G: SemigroupK[F] @@ -467,14 +419,21 @@ private[data] sealed trait RWSTSemigroupK[F[_], E, L, S] extends SemigroupK[Read } } -private[data] sealed trait RWSTMonadCombine[F[_], E, L, S] - extends MonadCombine[ReaderWriterStateT[F, E, L, S, ?]] with RWSTMonad[F, E, L, S] - with RWSTSemigroupK[F, E, L, S] with RWSTMonadTrans[E, L, S] { +private[data] sealed trait RWSTAlternative[F[_], E, L, S] + extends Alternative[ReaderWriterStateT[F, E, L, S, ?]] with RWSTFunctor[F, E, L, S] + with RWSTSemigroupK[F, E, L, S] { - implicit def F: MonadCombine[F] - override def G: MonadCombine[F] = F + implicit def F: Monad[F] + override def G: Alternative[F] + implicit def L: Monoid[L] + + def empty[A]: ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.lift(G.empty[A]) + + def pure[A](a: A): ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.pure[F, E, L, S, A](a) + + def ap[A, B](ff: ReaderWriterStateT[F, E, L, S, A => B])(fa: ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, B] = + ff.flatMap(f => fa.map(f)(F))(F, L) - def empty[A]: ReaderWriterStateT[F, E, L, S, A] = liftT[F, A](F.empty[A]) } private[data] sealed trait RWSTMonadError[F[_], E, L, S, R] @@ -490,27 +449,3 @@ private[data] sealed trait RWSTMonadError[F[_], E, L, S, R] } } -private[data] sealed trait RWSTMonadReader[F[_], E, L, S] - extends RWSTMonad[F, E, L, S] with MonadReader[ReaderWriterStateT[F, E, L, S, ?], E] { - - val ask: ReaderWriterStateT[F, E, L, S, E] = ReaderWriterStateT.ask - - def local[A](f: E => E)(fa: ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, A] = fa contramap f -} - -private[data] sealed trait RWSTMonadWriter[F[_], E, L, S] - extends RWSTMonad[F, E, L, S] with MonadWriter[ReaderWriterStateT[F, E, L, S, ?], L] { - - def writer[A](aw: (L, A)): ReaderWriterStateT[F, E, L, S, A] = - ReaderWriterStateT((_, s) => F.pure((aw._1, s, aw._2))) - - def listen[A](fa: ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, (L, A)] = - fa.transform { (l, s, a) => - (l, s, (l, a)) - } - - def pass[A](fa: ReaderWriterStateT[F, E, L, S, (L => L, A)]): ReaderWriterStateT[F, E, L, S, A] = - fa.transform { case (l, s, (fl, a)) => - (fl(l), s, a) - } -} diff --git a/core/src/main/scala/cats/data/StateT.scala b/core/src/main/scala/cats/data/StateT.scala index 61b643cba40..8b6c2f51f9b 100644 --- a/core/src/main/scala/cats/data/StateT.scala +++ b/core/src/main/scala/cats/data/StateT.scala @@ -164,19 +164,11 @@ object StateT extends StateTInstances { } private[data] sealed trait StateTInstances extends StateTInstances1 { - implicit def catsDataMonadStateForStateT[F[_], S](implicit F0: Monad[F]): MonadState[StateT[F, S, ?], S] = - new StateTMonadState[F, S] { implicit def F = F0 } - - implicit def catsDataMonadTransForStateT[S]: MonadTrans[StateT[?[_], S, ?]] = - new StateTMonadTrans[S] {} + implicit def catsDataAlternativeForStateT[F[_], S](implicit FM: Monad[F], FA: Alternative[F]): Alternative[StateT[F, S, ?]] = + new StateTAlternative[F, S] { implicit def F = FM; implicit def G = FA } } private[data] sealed trait StateTInstances1 extends StateTInstances2 { - implicit def catsDataMonadCombineForStateT[F[_], S](implicit F0: MonadCombine[F]): MonadCombine[StateT[F, S, ?]] = - new StateTMonadCombine[F, S] { implicit def F = F0 } -} - -private[data] sealed trait StateTInstances2 extends StateTInstances3 { implicit def catsDataMonadErrorForStateT[F[_], S, E](implicit F0: MonadError[F, E]): MonadError[StateT[F, S, ?], E] = new StateTMonadError[F, S, E] { implicit def F = F0 } @@ -184,12 +176,12 @@ private[data] sealed trait StateTInstances2 extends StateTInstances3 { new StateTSemigroupK[F, S] { implicit def F = F0; implicit def G = G0 } } -private[data] sealed trait StateTInstances3 extends StateTInstances4 { +private[data] sealed trait StateTInstances2 extends StateTInstances3 { implicit def catsDataMonadForStateT[F[_], S](implicit F0: Monad[F]): Monad[StateT[F, S, ?]] = new StateTMonad[F, S] { implicit def F = F0 } } -private[data] sealed trait StateTInstances4 { +private[data] sealed trait StateTInstances3 { implicit def catsDataFunctorForStateT[F[_], S](implicit F0: Functor[F]): Functor[StateT[F, S, ?]] = new StateTFunctor[F, S] { implicit def F = F0 } } @@ -230,10 +222,10 @@ private[data] abstract class StateFunctions { private[data] sealed trait StateTFunctor[F[_], S] extends Functor[StateT[F, S, ?]] { implicit def F: Functor[F] - def map[A, B](fa: StateT[F, S, A])(f: A => B): StateT[F, S, B] = fa.map(f) + override def map[A, B](fa: StateT[F, S, A])(f: A => B): StateT[F, S, B] = fa.map(f) } -private[data] sealed trait StateTMonad[F[_], S] extends Monad[StateT[F, S, ?]] { +private[data] sealed trait StateTMonad[F[_], S] extends Monad[StateT[F, S, ?]] with StateTFunctor[F, S] { implicit def F: Monad[F] def pure[A](a: A): StateT[F, S, A] = @@ -242,24 +234,12 @@ private[data] sealed trait StateTMonad[F[_], S] extends Monad[StateT[F, S, ?]] { def flatMap[A, B](fa: StateT[F, S, A])(f: A => StateT[F, S, B]): StateT[F, S, B] = fa.flatMap(f) - override def map[A, B](fa: StateT[F, S, A])(f: A => B): StateT[F, S, B] = fa.map(f) - def tailRecM[A, B](a: A)(f: A => StateT[F, S, Either[A, B]]): StateT[F, S, B] = StateT[F, S, B](s => F.tailRecM[(S, A), (S, B)]((s, a)) { case (s, a) => F.map(f(a).run(s)) { case (s, ab) => ab.bimap((s, _), (s, _)) } }) } -private[data] sealed trait StateTMonadState[F[_], S] extends MonadState[StateT[F, S, ?], S] with StateTMonad[F, S] { - lazy val get: StateT[F, S, S] = StateT(s => F.pure((s, s))) - - def set(s: S): StateT[F, S, Unit] = StateT(_ => F.pure((s, ()))) -} - -private[data] sealed trait StateTMonadTrans[S] extends MonadTrans[StateT[?[_], S, ?]] { - def liftT[M[_]: Monad, A](ma: M[A]): StateT[M, S, A] = StateT(s => Applicative[M].map(ma)(s -> _)) -} - private[data] sealed trait StateTSemigroupK[F[_], S] extends SemigroupK[StateT[F, S, ?]] { implicit def F: Monad[F] implicit def G: SemigroupK[F] @@ -268,11 +248,29 @@ private[data] sealed trait StateTSemigroupK[F[_], S] extends SemigroupK[StateT[F StateT(s => G.combineK(x.run(s), y.run(s))) } -private[data] sealed trait StateTMonadCombine[F[_], S] extends MonadCombine[StateT[F, S, ?]] with StateTMonad[F, S] with StateTSemigroupK[F, S] with StateTMonadTrans[S] { - implicit def F: MonadCombine[F] - override def G: MonadCombine[F] = F +private[data] sealed trait StateTAlternative[F[_], S] extends Alternative[StateT[F, S, ?]] with StateTFunctor[F, S] { + implicit def F: Monad[F] + def G: Alternative[F] + + def combineK[A](x: StateT[F, S, A], y: StateT[F, S, A]): StateT[F, S, A] = + StateT[F, S, A](s => G.combineK(x.run(s), y.run(s)))(G) + + def pure[A](a: A): StateT[F, S, A] = + StateT.pure[F, S, A](a)(G) + + def empty[A]: StateT[F, S, A] = + StateT.lift[F, S, A](G.empty[A])(G) + + override def ap[A, B](ff: StateT[F, S, A => B])(fa: StateT[F, S, A]): StateT[F, S, B] = + StateT[F, S, B]((s: S) => + F.flatMap(ff.run(s)) { sab => + val (sn, f) = sab + F.map(fa.run(sn)) { case (snn, a) => (snn, f(a)) } + } + ) + + override def map[A, B](fa: StateT[F, S, A])(f: A => B): StateT[F, S, B] = fa.map(f)(F) - def empty[A]: StateT[F, S, A] = liftT[F, A](F.empty[A]) } private[data] sealed trait StateTMonadError[F[_], S, E] extends StateTMonad[F, S] with MonadError[StateT[F, S, ?], E] { diff --git a/core/src/main/scala/cats/data/Tuple2K.scala b/core/src/main/scala/cats/data/Tuple2K.scala index 1c1b5c1c51e..dfa895a9f1a 100644 --- a/core/src/main/scala/cats/data/Tuple2K.scala +++ b/core/src/main/scala/cats/data/Tuple2K.scala @@ -13,10 +13,6 @@ final case class Tuple2K[F[_], G[_], A](first: F[A], second: G[A]) object Tuple2K extends Tuple2KInstances private[data] sealed abstract class Tuple2KInstances extends Tuple2KInstances0 { - implicit def catsDataMonadCombineForTuple2K[F[_], G[_]](implicit FF: MonadCombine[F], GF: MonadCombine[G]): MonadCombine[λ[α => Tuple2K[F, G, α]]] = new Tuple2KMonadCombine[F, G] { - def F: MonadCombine[F] = FF - def G: MonadCombine[G] = GF - } implicit def catsDataOrderForTuple2K[F[_], G[_], A](implicit FF: Order[F[A]], GF: Order[G[A]]): Order[Tuple2K[F, G, A]] = new Tuple2KOrder[F, G, A] { def F: Order[F[A]] = FF def G: Order[G[A]] = GF @@ -36,14 +32,6 @@ private[data] sealed abstract class Tuple2KInstances0 extends Tuple2KInstances1 def F: Traverse[F] = FF def G: Traverse[G] = GF } - implicit def catsDataAlternativeForTuple2K[F[_], G[_]](implicit FF: Alternative[F], GG: Alternative[G]): Alternative[λ[α => Tuple2K[F, G, α]]] = new Tuple2KAlternative[F, G] { - def F: Alternative[F] = FF - def G: Alternative[G] = GG - } - implicit def catsDataMonadForTuple2K[F[_], G[_]](implicit FM: Monad[F], GM: Monad[G]): Monad[λ[α => Tuple2K[F, G, α]]] = new Tuple2KMonad[F, G] { - def F: Monad[F] = FM - def G: Monad[G] = GM - } implicit def catsDataEqForTuple2K[F[_], G[_], A](implicit FF: Eq[F[A]], GG: Eq[G[A]]): Eq[Tuple2K[F, G, A]] = new Eq[Tuple2K[F, G, A]] { def eqv(x: Tuple2K[F, G, A], y: Tuple2K[F, G, A]): Boolean = FF.eqv(x.first, y.first) && GG.eqv(x.second, y.second) @@ -51,21 +39,35 @@ private[data] sealed abstract class Tuple2KInstances0 extends Tuple2KInstances1 } private[data] sealed abstract class Tuple2KInstances1 extends Tuple2KInstances2 { + implicit def catsDataAlternativeForTuple2K[F[_], G[_]](implicit FF: Alternative[F], GG: Alternative[G]): Alternative[λ[α => Tuple2K[F, G, α]]] = new Tuple2KAlternative[F, G] { + def F: Alternative[F] = FF + def G: Alternative[G] = GG + } implicit def catsDataFoldableForTuple2K[F[_], G[_]](implicit FF: Foldable[F], GF: Foldable[G]): Foldable[λ[α => Tuple2K[F, G, α]]] = new Tuple2KFoldable[F, G] { def F: Foldable[F] = FF def G: Foldable[G] = GF } +} + +private[data] sealed abstract class Tuple2KInstances2 extends Tuple2KInstances3 { + implicit def catsDataMonadForTuple2K[F[_], G[_]](implicit FM: Monad[F], GM: Monad[G]): Monad[λ[α => Tuple2K[F, G, α]]] = new Tuple2KMonad[F, G] { + def F: Monad[F] = FM + def G: Monad[G] = GM + } implicit def catsDataMonoidKForTuple2K[F[_], G[_]](implicit FF: MonoidK[F], GG: MonoidK[G]): MonoidK[λ[α => Tuple2K[F, G, α]]] = new Tuple2KMonoidK[F, G] { def F: MonoidK[F] = FF def G: MonoidK[G] = GG } +} + +private[data] sealed abstract class Tuple2KInstances3 extends Tuple2KInstances4 { implicit def catsDataApplicativeForTuple2K[F[_], G[_]](implicit FF: Applicative[F], GG: Applicative[G]): Applicative[λ[α => Tuple2K[F, G, α]]] = new Tuple2KApplicative[F, G] { def F: Applicative[F] = FF def G: Applicative[G] = GG } } -private[data] sealed abstract class Tuple2KInstances2 extends Tuple2KInstances3 { +private[data] sealed abstract class Tuple2KInstances4 extends Tuple2KInstances5 { implicit def catsDataSemigroupKForTuple2K[F[_], G[_]](implicit FF: SemigroupK[F], GG: SemigroupK[G]): SemigroupK[λ[α => Tuple2K[F, G, α]]] = new Tuple2KSemigroupK[F, G] { def F: SemigroupK[F] = FF def G: SemigroupK[G] = GG @@ -76,7 +78,7 @@ private[data] sealed abstract class Tuple2KInstances2 extends Tuple2KInstances3 } } -private[data] sealed abstract class Tuple2KInstances3 { +private[data] sealed abstract class Tuple2KInstances5 { implicit def catsDataFunctorForTuple2K[F[_], G[_]](implicit FF: Functor[F], GG: Functor[G]): Functor[λ[α => Tuple2K[F, G, α]]] = new Tuple2KFunctor[F, G] { def F: Functor[F] = FF def G: Functor[G] = GG @@ -162,12 +164,6 @@ private[data] sealed trait Tuple2KTraverse[F[_], G[_]] extends Traverse[λ[α => H.map2(F.traverse(fa.first)(f), G.traverse(fa.second)(f))(Tuple2K(_, _)) } -private[data] sealed trait Tuple2KMonadCombine[F[_], G[_]] extends MonadCombine[λ[α => Tuple2K[F, G, α]]] - with Tuple2KMonad[F, G] with Tuple2KAlternative[F, G] { - def F: MonadCombine[F] - def G: MonadCombine[G] -} - private[data] sealed trait Tuple2KShow[F[_], G[_], A] extends Show[Tuple2K[F, G, A]] { def F: Show[F[A]] def G: Show[G[A]] diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index ee2e5a878f7..204d99e7b58 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -75,9 +75,11 @@ private[data] sealed abstract class WriterTInstances extends WriterTInstances0 { } private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 { - - implicit def catsDataMonadForWriterTId[L:Monoid]: Monad[WriterT[Id, L, ?]] = - catsDataMonadWriterForWriterT[Id, L] + implicit def catsDataMonadErrorForWriterT[F[_], L, E](implicit F: MonadError[F, E], L: Monoid[L]): MonadError[WriterT[F, L, ?], E] = + new WriterTMonadError[F, L, E] { + implicit val F0: MonadError[F, E] = F + implicit val L0: Monoid[L] = L + } implicit def catsDataEqForWriterTId[L: Eq, V: Eq]: Eq[WriterT[Id, L, V]] = catsDataEqForWriterT[Id, L, V] @@ -88,12 +90,6 @@ private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 fab.bimap(f, g) } - implicit def catsDataMonadTransForWriterT[W](implicit W: Monoid[W]): MonadTrans[WriterT[?[_], W, ?]] = - new MonadTrans[WriterT[?[_], W, ?]] { - def liftT[M[_]: Monad, A](ma: M[A]): WriterT[M, W, A] = - WriterT(Functor[M].map(ma)((W.empty, _))) - } - implicit def catsDataShowForWriterT[F[_], L, V](implicit F: Show[F[(L, V)]]): Show[WriterT[F, L, V]] = new Show[WriterT[F, L, V]] { override def show(f: WriterT[F, L, V]): String = f.show } @@ -103,14 +99,8 @@ private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 } private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 { - implicit def catsDataMonadCombineForWriterT[F[_], L](implicit F: MonadCombine[F], L: Monoid[L]): MonadCombine[WriterT[F, L, ?]] = - new WriterTMonadCombine[F, L] { - implicit val F0: MonadCombine[F] = F - implicit val L0: Monoid[L] = L - } - - implicit def catsDataFlatMapForWriterTId[L:Semigroup]: FlatMap[WriterT[Id, L, ?]] = - catsDataFlatMapForWriterT2[Id, L] + implicit def catsDataMonadForWriterTId[L:Monoid]: Monad[WriterT[Id, L, ?]] = + catsDataMonadForWriterT[Id, L] implicit def catsDataEqForWriterT[F[_], L, V](implicit F: Eq[F[(L, V)]]): Eq[WriterT[F, L, V]] = F.on(_.run) @@ -120,9 +110,9 @@ private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 } private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 { - implicit def catsDataMonadFilterForWriterT[F[_], L](implicit F: MonadFilter[F], L: Monoid[L]): MonadFilter[WriterT[F, L, ?]] = - new WriterTMonadFilter[F, L] { - implicit val F0: MonadFilter[F] = F + implicit def catsDataMonadForWriterT[F[_], L](implicit F: Monad[F], L: Monoid[L]): Monad[WriterT[F, L, ?]] = + new WriterTMonad[F, L] { + implicit val F0: Monad[F] = F implicit val L0: Monoid[L] = L } @@ -136,9 +126,14 @@ private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 } private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 { - implicit def catsDataMonadWriterForWriterT[F[_], L](implicit F: Monad[F], L: Monoid[L]): MonadWriter[WriterT[F, L, ?], L] = - new WriterTMonadWriter[F, L] { - implicit val F0: Monad[F] = F + implicit def catsDataFlatMapForWriterTId[L:Semigroup]: FlatMap[WriterT[Id, L, ?]] = + catsDataFlatMapForWriterT2[Id, L] +} + +private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5 { + implicit def catsDataFlatMapForWriterT1[F[_], L](implicit F: FlatMap[F], L: Monoid[L]): FlatMap[WriterT[F, L, ?]] = + new WriterTFlatMap1[F, L] { + implicit val F0: FlatMap[F] = F implicit val L0: Monoid[L] = L } @@ -148,51 +143,54 @@ private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 } } -private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5 { - implicit def catsDataAlternativeForWriterT[F[_], L](implicit F: Alternative[F], L: Monoid[L]): Alternative[WriterT[F, L, ?]] = - new WriterTAlternative[F, L] { - implicit val F0: Alternative[F] = F +private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6 { + implicit def catsDataApplicativeErrorForWriterT[F[_], L, E](implicit F: ApplicativeError[F, E], L: Monoid[L]): ApplicativeError[WriterT[F, L, ?], E] = + new WriterTApplicativeError[F, L, E] { + implicit val F0: ApplicativeError[F, E] = F implicit val L0: Monoid[L] = L } - } -private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6 { - implicit def catsDataApplicativeForWriterT[F[_], L](implicit F: Applicative[F], L: Monoid[L]): Applicative[WriterT[F, L, ?]] = - new WriterTApplicative[F, L] { - implicit val F0: Applicative[F] = F +private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 { + implicit def catsDataAlternativeForWriterT[F[_], L](implicit F: Alternative[F], L: Monoid[L]): Alternative[WriterT[F, L, ?]] = + new WriterTAlternative[F, L] { + implicit val F0: Alternative[F] = F implicit val L0: Monoid[L] = L } +} +private[data] sealed abstract class WriterTInstances7 extends WriterTInstances8 { implicit def catsDataMonoidKForWriterT[F[_], L](implicit F: MonoidK[F]): MonoidK[WriterT[F, L, ?]] = new WriterTMonoidK[F, L] { implicit val F0: MonoidK[F] = F } -} -private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 { - implicit def catsDataFlatMapForWriterT1[F[_], L](implicit F: FlatMap[F], L: Monoid[L]): FlatMap[WriterT[F, L, ?]] = - new WriterTFlatMap1[F, L] { - implicit val F0: FlatMap[F] = F - implicit val L0: Monoid[L] = L + implicit def catsDataFlatMapForWriterT2[F[_], L](implicit F: Monad[F], L: Semigroup[L]): FlatMap[WriterT[F, L, ?]] = + new WriterTFlatMap2[F, L] { + implicit val F0: Monad[F] = F + implicit val L0: Semigroup[L] = L } + implicit def catsDataContravariantForWriterT[F[_], L](implicit F: Contravariant[F]): Contravariant[WriterT[F, L, ?]] = new WriterTContravariant[F, L] { + implicit val F0: Contravariant[F] = F + } +} + +private[data] sealed abstract class WriterTInstances8 extends WriterTInstances9 { implicit def catsDataSemigroupKForWriterT[F[_], L](implicit F: SemigroupK[F]): SemigroupK[WriterT[F, L, ?]] = new WriterTSemigroupK[F, L] { implicit val F0: SemigroupK[F] = F } -} -private[data] sealed abstract class WriterTInstances7 extends WriterTInstances8 { - implicit def catsDataFlatMapForWriterT2[F[_], L](implicit F: Monad[F], L: Semigroup[L]): FlatMap[WriterT[F, L, ?]] = - new WriterTFlatMap2[F, L] { - implicit val F0: Monad[F] = F - implicit val L0: Semigroup[L] = L + implicit def catsDataApplicativeForWriterT[F[_], L](implicit F: Applicative[F], L: Monoid[L]): Applicative[WriterT[F, L, ?]] = + new WriterTApplicative[F, L] { + implicit val F0: Applicative[F] = F + implicit val L0: Monoid[L] = L } -} -private[data] sealed abstract class WriterTInstances8 extends WriterTInstances9 { +} +private[data] sealed abstract class WriterTInstances9 extends WriterTInstances10 { implicit def catsDataApplyForWriterT[F[_], L](implicit F: Apply[F], L: Semigroup[L]): Apply[WriterT[F, L, ?]] = new WriterTApply[F, L] { implicit val F0: Apply[F] = F @@ -200,31 +198,11 @@ private[data] sealed abstract class WriterTInstances8 extends WriterTInstances9 } } -private[data] sealed abstract class WriterTInstances9 extends WriterTInstances10 { +private[data] sealed abstract class WriterTInstances10 { implicit def catsDataCoflatMapForWriterT[F[_], L](implicit F: Functor[F]): CoflatMap[WriterT[F, L, ?]] = new WriterTCoflatMap[F, L] { implicit val F0: Functor[F] = F } - - implicit def catsDataContravariantForWriterT[F[_], L](implicit F: Contravariant[F]): Contravariant[WriterT[F, L, ?]] = new WriterTContravariant[F, L] { - implicit val F0: Contravariant[F] = F - } -} - -private[data] sealed abstract class WriterTInstances10 extends WriterTInstances11 { - implicit def catsDataMonadErrorForWriterT[F[_], L, E](implicit F: MonadError[F, E], L: Monoid[L]): MonadError[WriterT[F, L, ?], E] = - new WriterTMonadError[F, L, E] { - implicit val F0: MonadError[F, E] = F - implicit val L0: Monoid[L] = L - } -} - -private[data] sealed abstract class WriterTInstances11 { - implicit def catsDataApplicativeErrorForWriterT[F[_], L, E](implicit F: ApplicativeError[F, E], L: Monoid[L]): ApplicativeError[WriterT[F, L, ?], E] = - new WriterTApplicativeError[F, L, E] { - implicit val F0: ApplicativeError[F, E] = F - implicit val L0: Monoid[L] = L - } } private[data] sealed trait WriterTFunctor[F[_], L] extends Functor[WriterT[F, L, ?]] { @@ -317,7 +295,6 @@ private[data] sealed trait WriterTApplicative[F[_], L] extends WriterTApply[F, L private[data] sealed trait WriterTMonad[F[_], L] extends WriterTApplicative[F, L] with WriterTFlatMap1[F, L] with Monad[WriterT[F, L, ?]] { override implicit def F0: Monad[F] override implicit def L0: Monoid[L] - } private[data] sealed trait WriterTApplicativeError[F[_], L, E] extends ApplicativeError[WriterT[F, L, ?], E] with WriterTApplicative[F, L] { @@ -333,19 +310,6 @@ private[data] sealed trait WriterTMonadError[F[_], L, E] extends MonadError[Writ override implicit def F0: MonadError[F, E] } -private[data] sealed trait WriterTMonadWriter[F[_], L] extends MonadWriter[WriterT[F, L, ?], L] with WriterTMonad[F, L] { - def writer[A](aw: (L, A)): WriterT[F, L, A] = - WriterT.put(aw._2)(aw._1) - - def listen[A](fa: WriterT[F, L, A]): WriterT[F, L, (L, A)] = - WriterT(F0.flatMap(fa.value)(a => F0.map(fa.written)(l => (l, (l, a))))) - - def pass[A](fa: WriterT[F, L, (L => L, A)]): WriterT[F, L, A] = - WriterT(F0.flatMap(fa.value) { case (f, a) => F0.map(fa.written)(l => (f(l), a)) }) - - override def tell(l: L): WriterT[F, L, Unit] = WriterT.tell(l) -} - private[data] sealed trait WriterTSemigroupK[F[_], L] extends SemigroupK[WriterT[F, L, ?]] { implicit def F0: SemigroupK[F] @@ -363,16 +327,6 @@ private[data] sealed trait WriterTAlternative[F[_], L] extends Alternative[Write override implicit def F0: Alternative[F] } -private[data] sealed trait WriterTMonadFilter[F[_], L] extends MonadFilter[WriterT[F, L, ?]] with WriterTMonad[F, L] { - override implicit def F0: MonadFilter[F] - - def empty[A]: WriterT[F, L, A] = WriterT(F0.empty) -} - -private[data] sealed trait WriterTMonadCombine[F[_], L] extends MonadCombine[WriterT[F, L, ?]] with WriterTMonad[F, L] with WriterTAlternative[F, L] { - override implicit def F0: MonadCombine[F] -} - private[data] sealed trait WriterTSemigroup[F[_], L, A] extends Semigroup[WriterT[F, L, A]] { implicit def F0: Semigroup[F[(L, A)]] diff --git a/core/src/main/scala/cats/data/package.scala b/core/src/main/scala/cats/data/package.scala index 0ad5e3740ec..e367b1599ca 100644 --- a/core/src/main/scala/cats/data/package.scala +++ b/core/src/main/scala/cats/data/package.scala @@ -35,9 +35,9 @@ package object data { type RWST[F[_], E, S, L, A] = ReaderWriterStateT[F, E, S, L, A] val RWST = ReaderWriterStateT - type ReaderWriterState[E, S, L, A] = ReaderWriterStateT[Eval, E, S, L, A] + type ReaderWriterState[E, L, S, A] = ReaderWriterStateT[Eval, E, L, S, A] object ReaderWriterState extends RWSFunctions - type RWS[E, S, L, A] = ReaderWriterState[E, S, L, A] + type RWS[E, L, S, A] = ReaderWriterState[E, L, S, A] val RWS = ReaderWriterState } diff --git a/core/src/main/scala/cats/instances/function.scala b/core/src/main/scala/cats/instances/function.scala index 3aa53cb3df8..49463671e1f 100644 --- a/core/src/main/scala/cats/instances/function.scala +++ b/core/src/main/scala/cats/instances/function.scala @@ -42,17 +42,13 @@ private[instances] sealed trait Function1Instances { fa.compose(f) } - implicit def catsStdMonadReaderForFunction1[T1]: MonadReader[T1 => ?, T1] = - new MonadReader[T1 => ?, T1] { + implicit def catsStdMonadForFunction1[T1]: Monad[T1 => ?] = + new Monad[T1 => ?] { def pure[R](r: R): T1 => R = _ => r def flatMap[R1, R2](fa: T1 => R1)(f: R1 => T1 => R2): T1 => R2 = t => f(fa(t))(t) - val ask: T1 => T1 = identity - - def local[A](f: T1 => T1)(fa: T1 => A): T1 => A = f.andThen(fa) - override def map[R1, R2](fa: T1 => R1)(f: R1 => R2): T1 => R2 = f.compose(fa) diff --git a/core/src/main/scala/cats/instances/list.scala b/core/src/main/scala/cats/instances/list.scala index eb203aed250..df4bdec252e 100644 --- a/core/src/main/scala/cats/instances/list.scala +++ b/core/src/main/scala/cats/instances/list.scala @@ -8,8 +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] = - new TraverseFilter[List] with MonadCombine[List] with Monad[List] with CoflatMap[List] { + implicit val catsStdInstancesForList: Traverse[List] with Alternative[List] with Monad[List] with CoflatMap[List] = + new Traverse[List] with Alternative[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 @@ -60,12 +60,7 @@ trait ListInstances extends cats.kernel.instances.ListInstances { Eval.defer(loop(fa)) } - def traverseFilter[G[_], A, B](fa: List[A])(f: A => G[Option[B]])(implicit G: Applicative[G]): G[List[B]] = - foldRight[A, G[List[B]]](fa, Always(G.pure(List.empty))){ (a, lglb) => - G.map2Eval(f(a), lglb)((ob, l) => ob.fold(l)(_ :: l)) - }.value - - override def traverse[G[_], A, B](fa: List[A])(f: A => G[B])(implicit G: Applicative[G]): G[List[B]] = + def traverse[G[_], A, B](fa: List[A])(f: A => G[B])(implicit G: Applicative[G]): G[List[B]] = foldRight[A, G[List[B]]](fa, Always(G.pure(List.empty))){ (a, lglb) => G.map2Eval(f(a), lglb)(_ :: _) }.value @@ -94,8 +89,6 @@ trait ListInstances extends cats.kernel.instances.ListInstances { override def isEmpty[A](fa: List[A]): Boolean = fa.isEmpty - override def filter[A](fa: List[A])(f: A => Boolean): List[A] = fa.filter(f) - override def foldM[G[_], A, B](fa: List[A], z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = { def step(in: (List[A], B)): G[Either[(List[A], B), B]] = in match { case (Nil, b) => G.pure(Right(b)) diff --git a/core/src/main/scala/cats/instances/map.scala b/core/src/main/scala/cats/instances/map.scala index b16f4c5eb46..4074f7419bd 100644 --- a/core/src/main/scala/cats/instances/map.scala +++ b/core/src/main/scala/cats/instances/map.scala @@ -14,10 +14,10 @@ trait MapInstances extends cats.kernel.instances.MapInstances { } // scalastyle:off method.length - implicit def catsStdInstancesForMap[K]: TraverseFilter[Map[K, ?]] with FlatMap[Map[K, ?]] = - new TraverseFilter[Map[K, ?]] with FlatMap[Map[K, ?]] { + implicit def catsStdInstancesForMap[K]: Traverse[Map[K, ?]] with FlatMap[Map[K, ?]] = + new Traverse[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]] = { + 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)) val gbb = Foldable.iterateRight(fa.iterator, gba){ (kv, lbuf) => G.map2Eval(f(kv._2), lbuf)({ (b, buf) => buf + (kv._1 -> b)}) @@ -25,14 +25,6 @@ trait MapInstances extends cats.kernel.instances.MapInstances { G.map(gbb)(_.toMap) } - def traverseFilter[G[_], A, B](fa: Map[K, A])(f: A => G[Option[B]])(implicit G: Applicative[G]): G[Map[K, B]] = { - val gba: Eval[G[Map[K, B]]] = Always(G.pure(Map.empty)) - val gbb = Foldable.iterateRight(fa.iterator, gba){ (kv, lbuf) => - G.map2Eval(f(kv._2), lbuf)({ (ob, buf) => ob.fold(buf)(b => buf + (kv._1 -> b))}) - }.value - G.map(gbb)(_.toMap) - } - override def map[A, B](fa: Map[K, A])(f: A => B): Map[K, B] = fa.map { case (k, a) => (k, f(a)) } diff --git a/core/src/main/scala/cats/instances/option.scala b/core/src/main/scala/cats/instances/option.scala index be654f0d3a9..5f33310454d 100644 --- a/core/src/main/scala/cats/instances/option.scala +++ b/core/src/main/scala/cats/instances/option.scala @@ -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 CommutativeMonad[Option] with CoflatMap[Option] with Alternative[Option] = - new TraverseFilter[Option] with MonadError[Option, Unit] with MonadCombine[Option] with CommutativeMonad[Option] with CoflatMap[Option] with Alternative[Option] { + implicit val catsStdInstancesForOption: Traverse[Option] with MonadError[Option, Unit] with Alternative[Option] with CommutativeMonad[Option] with CoflatMap[Option] = + new Traverse[Option] with MonadError[Option, Unit] with Alternative[Option] with CommutativeMonad[Option] with CoflatMap[Option] { def empty[A]: Option[A] = None @@ -56,21 +56,12 @@ trait OptionInstances extends cats.kernel.instances.OptionInstances { def handleErrorWith[A](fa: Option[A])(f: (Unit) => Option[A]): Option[A] = fa orElse f(()) - def traverseFilter[G[_], A, B](fa: Option[A])(f: A => G[Option[B]])(implicit G: Applicative[G]): G[Option[B]] = - fa match { - case None => G.pure(None) - case Some(a) => f(a) - } - - override def traverse[G[_]: Applicative, A, B](fa: Option[A])(f: A => G[B]): G[Option[B]] = + def traverse[G[_]: Applicative, A, B](fa: Option[A])(f: A => G[B]): G[Option[B]] = fa match { case None => Applicative[G].pure(None) case Some(a) => Applicative[G].map(f(a))(Some(_)) } - override def filter[A](fa: Option[A])(p: A => Boolean): Option[A] = - fa.filter(p) - override def reduceLeftToOption[A, B](fa: Option[A])(f: A => B)(g: (B, A) => B): Option[B] = fa.map(f) diff --git a/core/src/main/scala/cats/instances/stream.scala b/core/src/main/scala/cats/instances/stream.scala index 08705b2ee63..c4343636519 100644 --- a/core/src/main/scala/cats/instances/stream.scala +++ b/core/src/main/scala/cats/instances/stream.scala @@ -6,8 +6,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] = - new TraverseFilter[Stream] with MonadCombine[Stream] with CoflatMap[Stream] { + implicit val catsStdInstancesForStream: Traverse[Stream] with Alternative[Stream] with Monad[Stream] with CoflatMap[Stream] = + new Traverse[Stream] with Alternative[Stream] with Monad[Stream] with CoflatMap[Stream] { def empty[A]: Stream[A] = Stream.Empty @@ -34,16 +34,7 @@ trait StreamInstances extends cats.kernel.instances.StreamInstances { if (s.isEmpty) lb else f(s.head, Eval.defer(foldRight(s.tail, lb)(f))) } - def traverseFilter[G[_], A, B](fa: Stream[A])(f: A => G[Option[B]])(implicit G: Applicative[G]): G[Stream[B]] = { - // We use foldRight to avoid possible stack overflows. Since - // we don't want to return a Eval[_] instance, we call .value - // at the end. - foldRight(fa, Always(G.pure(Stream.empty[B]))){ (a, lgsb) => - G.map2Eval(f(a), lgsb)((ob, s) => ob.fold(s)(_ #:: s)) - }.value - } - - override def traverse[G[_], A, B](fa: Stream[A])(f: A => G[B])(implicit G: Applicative[G]): G[Stream[B]] = { + def traverse[G[_], A, B](fa: Stream[A])(f: A => G[B])(implicit G: Applicative[G]): G[Stream[B]] = { // We use foldRight to avoid possible stack overflows. Since // we don't want to return a Eval[_] instance, we call .value // at the end. @@ -118,10 +109,6 @@ trait StreamInstances extends cats.kernel.instances.StreamInstances { override def isEmpty[A](fa: Stream[A]): Boolean = fa.isEmpty - override def filter[A](fa: Stream[A])(f: A => Boolean): Stream[A] = fa.filter(f) - - override def collect[A, B](fa: Stream[A])(f: PartialFunction[A, B]): Stream[B] = fa.collect(f) - override def foldM[G[_], A, B](fa: Stream[A], z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = { def step(in: (Stream[A], B)): G[Either[(Stream[A], B), B]] = { val (s, b) = in diff --git a/core/src/main/scala/cats/instances/vector.scala b/core/src/main/scala/cats/instances/vector.scala index 5c466aa76c1..6675f121ca5 100644 --- a/core/src/main/scala/cats/instances/vector.scala +++ b/core/src/main/scala/cats/instances/vector.scala @@ -8,8 +8,8 @@ import scala.collection.immutable.VectorBuilder import list._ trait VectorInstances extends cats.kernel.instances.VectorInstances { - implicit val catsStdInstancesForVector: TraverseFilter[Vector] with MonadCombine[Vector] with CoflatMap[Vector] = - new TraverseFilter[Vector] with MonadCombine[Vector] with CoflatMap[Vector] { + implicit val catsStdInstancesForVector: Traverse[Vector] with Monad[Vector] with Alternative[Vector] with CoflatMap[Vector] = + new Traverse[Vector] with Monad[Vector] with Alternative[Vector] with CoflatMap[Vector] { def empty[A]: Vector[A] = Vector.empty[A] @@ -23,9 +23,6 @@ trait VectorInstances extends cats.kernel.instances.VectorInstances { def flatMap[A, B](fa: Vector[A])(f: A => Vector[B]): Vector[B] = fa.flatMap(f) - override def map2[A, B, Z](fa: Vector[A], fb: Vector[B])(f: (A, B) => Z): Vector[Z] = - fa.flatMap(a => fb.map(b => f(a, b))) - def coflatMap[A, B](fa: Vector[A])(f: Vector[A] => B): Vector[B] = { @tailrec def loop(builder: VectorBuilder[B], as: Vector[A]): Vector[B] = as match { @@ -44,11 +41,6 @@ trait VectorInstances extends cats.kernel.instances.VectorInstances { Eval.defer(loop(0)) } - def traverseFilter[G[_], A, B](fa: Vector[A])(f: A => G[Option[B]])(implicit G: Applicative[G]): G[Vector[B]] = - foldRight[A, G[Vector[B]]](fa, Always(G.pure(Vector.empty))){ (a, lgvb) => - G.map2Eval(f(a), lgvb)((ob, v) => ob.fold(v)(_ +: v)) - }.value - def tailRecM[A, B](a: A)(fn: A => Vector[Either[A, B]]): Vector[B] = { val buf = Vector.newBuilder[B] var state = List(fn(a).iterator) @@ -93,10 +85,6 @@ trait VectorInstances extends cats.kernel.instances.VectorInstances { override def isEmpty[A](fa: Vector[A]): Boolean = fa.isEmpty - override def filter[A](fa: Vector[A])(f: A => Boolean): Vector[A] = fa.filter(f) - - override def collect[A, B](fa: Vector[A])(f: PartialFunction[A, B]): Vector[B] = fa.collect(f) - override def foldM[G[_], A, B](fa: Vector[A], z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = Foldable[List].foldM(fa.toList, z)(f) diff --git a/core/src/main/scala/cats/syntax/all.scala b/core/src/main/scala/cats/syntax/all.scala index 67d4b2c2353..2f6d9be4505 100644 --- a/core/src/main/scala/cats/syntax/all.scala +++ b/core/src/main/scala/cats/syntax/all.scala @@ -2,7 +2,8 @@ package cats package syntax trait AllSyntax - extends ApplicativeSyntax + extends AlternativeSyntax + with ApplicativeSyntax with ApplicativeErrorSyntax with ApplySyntax with ArrowSyntax @@ -20,16 +21,12 @@ trait AllSyntax with FlatMapSyntax with FoldableSyntax with FunctorSyntax - with FunctorFilterSyntax with GroupSyntax with InvariantSyntax with IorSyntax with ListSyntax - with MonadCombineSyntax with MonadErrorSyntax - with MonadFilterSyntax with MonadSyntax - with MonadTransSyntax with MonoidSyntax with OptionSyntax with OrderSyntax @@ -40,7 +37,6 @@ trait AllSyntax with SemigroupKSyntax with ShowSyntax with StrongSyntax - with TraverseFilterSyntax with TraverseSyntax with NonEmptyTraverseSyntax with ValidatedSyntax diff --git a/core/src/main/scala/cats/syntax/alternative.scala b/core/src/main/scala/cats/syntax/alternative.scala new file mode 100644 index 00000000000..158d623d46b --- /dev/null +++ b/core/src/main/scala/cats/syntax/alternative.scala @@ -0,0 +1,49 @@ +package cats +package syntax + +trait AlternativeSyntax { + // TODO: use simulacrum instances eventually + implicit final def catsSyntaxUnite[F[_], G[_], A](fga: F[G[A]]): UniteOps[F, G, A] = + new UniteOps[F, G, A](fga) + + implicit final def catsSyntaxAlternativeSeparate[F[_], G[_, _], A, B](fgab: F[G[A, B]]): SeparateOps[F, G, A, B] = + new SeparateOps[F, G, A, B](fgab) +} + +final class UniteOps[F[_], G[_], A](val fga: F[G[A]]) extends AnyVal { + + /** + * @see [[Alternative.unite]] + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val x: List[Vector[Int]] = List(Vector(1, 2), Vector(3, 4)) + * scala> x.unite + * res0: List[Int] = List(1, 2, 3, 4) + * }}} + */ + def unite(implicit + F: Monad[F], + A: Alternative[F], + G: Foldable[G]): F[A] = A.unite[G, A](fga) +} + +final class SeparateOps[F[_], G[_, _], A, B](val fgab: F[G[A, B]]) extends AnyVal { + + /** + * @see [[Alternative.separate]] + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val l: List[Either[String, Int]] = List(Right(1), Left("error")) + * scala> l.separate + * res0: (List[String], List[Int]) = (List(error),List(1)) + * }}} + */ + def separate(implicit + F: Monad[F], + A: Alternative[F], + G: Bifoldable[G]): (F[A], F[B]) = A.separate[G, A, B](fgab) +} diff --git a/core/src/main/scala/cats/syntax/functorFilter.scala b/core/src/main/scala/cats/syntax/functorFilter.scala deleted file mode 100644 index a80b6c2618e..00000000000 --- a/core/src/main/scala/cats/syntax/functorFilter.scala +++ /dev/null @@ -1,4 +0,0 @@ -package cats -package syntax - -trait FunctorFilterSyntax extends FunctorFilter.ToFunctorFilterOps diff --git a/core/src/main/scala/cats/syntax/monadCombine.scala b/core/src/main/scala/cats/syntax/monadCombine.scala deleted file mode 100644 index f970cf6b9b4..00000000000 --- a/core/src/main/scala/cats/syntax/monadCombine.scala +++ /dev/null @@ -1,43 +0,0 @@ -package cats -package syntax - -trait MonadCombineSyntax { - // TODO: use simulacrum instances eventually - implicit final def catsSyntaxMonadCombine[F[_]: MonadCombine, G[_], A](fga: F[G[A]]): MonadCombineOps[F, G, A] = - new MonadCombineOps[F, G, A](fga) - - implicit final def catsSyntaxMonadCombineSeparate[F[_]: MonadCombine, G[_, _], A, B](fgab: F[G[A, B]]): SeparateOps[F, G, A, B] = - new SeparateOps[F, G, A, B](fgab) -} - -final class MonadCombineOps[F[_], G[_], A](val fga: F[G[A]]) extends AnyVal { - - /** - * @see [[MonadCombine.unite]] - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val x: List[Vector[Int]] = List(Vector(1, 2), Vector(3, 4)) - * scala> x.unite - * res0: List[Int] = List(1, 2, 3, 4) - * }}} - */ - def unite(implicit F: MonadCombine[F], G: Foldable[G]): F[A] = F.unite(fga) -} - -final class SeparateOps[F[_], G[_, _], A, B](val fgab: F[G[A, B]]) extends AnyVal { - - /** - * @see [[MonadCombine.separate]] - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l: List[Either[String, Int]] = List(Right(1), Left("error")) - * scala> l.separate - * res0: (List[String], List[Int]) = (List(error),List(1)) - * }}} - */ - def separate(implicit F: MonadCombine[F], G: Bifoldable[G]): (F[A], F[B]) = F.separate(fgab) -} diff --git a/core/src/main/scala/cats/syntax/monadFilter.scala b/core/src/main/scala/cats/syntax/monadFilter.scala deleted file mode 100644 index ee9208eaaf2..00000000000 --- a/core/src/main/scala/cats/syntax/monadFilter.scala +++ /dev/null @@ -1,5 +0,0 @@ -package cats -package syntax - -trait MonadFilterSyntax extends MonadFilter.ToMonadFilterOps - diff --git a/core/src/main/scala/cats/syntax/monadTrans.scala b/core/src/main/scala/cats/syntax/monadTrans.scala deleted file mode 100644 index 11a4ddae391..00000000000 --- a/core/src/main/scala/cats/syntax/monadTrans.scala +++ /dev/null @@ -1,11 +0,0 @@ -package cats -package syntax - -trait MonadTransSyntax { - implicit final def catsSyntaxMonadTrans[F[_], A](fa: F[A]): MonadTransOps[F, A] = new MonadTransOps(fa) -} - -final class MonadTransOps[F[_], A](val fa: F[A]) extends AnyVal { - def liftT[MT[_[_], _]](implicit F: Monad[F], MT: MonadTrans[MT]): MT[F, A] = - MT.liftT(fa) -} diff --git a/core/src/main/scala/cats/syntax/package.scala b/core/src/main/scala/cats/syntax/package.scala index 44abb61a08c..f8c035de2a0 100644 --- a/core/src/main/scala/cats/syntax/package.scala +++ b/core/src/main/scala/cats/syntax/package.scala @@ -2,6 +2,7 @@ package cats package object syntax { object all extends AllSyntax + object alternative extends AlternativeSyntax object applicative extends ApplicativeSyntax object applicativeError extends ApplicativeErrorSyntax object apply extends ApplySyntax @@ -20,15 +21,12 @@ package object syntax { object flatMap extends FlatMapSyntax object foldable extends FoldableSyntax object functor extends FunctorSyntax - object functorFilter extends FunctorFilterSyntax object group extends GroupSyntax object invariant extends InvariantSyntax object ior extends IorSyntax object list extends ListSyntax object monad extends MonadSyntax - object monadCombine extends MonadCombineSyntax object monadError extends MonadErrorSyntax - object monadFilter extends MonadFilterSyntax object monoid extends MonoidSyntax object option extends OptionSyntax object order extends OrderSyntax @@ -39,10 +37,8 @@ package object syntax { object semigroupk extends SemigroupKSyntax object show extends ShowSyntax object strong extends StrongSyntax - object monadTrans extends MonadTransSyntax object traverse extends TraverseSyntax object nonEmptyTraverse extends NonEmptyTraverseSyntax - object traverseFilter extends TraverseFilterSyntax object validated extends ValidatedSyntax object vector extends VectorSyntax object writer extends WriterSyntax diff --git a/core/src/main/scala/cats/syntax/traverseFilter.scala b/core/src/main/scala/cats/syntax/traverseFilter.scala deleted file mode 100644 index 794caeddee1..00000000000 --- a/core/src/main/scala/cats/syntax/traverseFilter.scala +++ /dev/null @@ -1,4 +0,0 @@ -package cats -package syntax - -trait TraverseFilterSyntax extends TraverseFilter.ToTraverseFilterOps diff --git a/docs/src/main/tut/datatypes/freemonad.md b/docs/src/main/tut/datatypes/freemonad.md index 9febc17f2fb..d99083c8d0f 100644 --- a/docs/src/main/tut/datatypes/freemonad.md +++ b/docs/src/main/tut/datatypes/freemonad.md @@ -520,29 +520,25 @@ final case class ReadLine(prompt : String) extends Teletype[String] type TeletypeT[M[_], A] = FreeT[Teletype, M, A] type Log = List[String] +type TeletypeState[A] = State[List[String], A] + /** Smart constructors, notice we are abstracting over any MonadState instance * to potentially support other types beside State */ -class TeletypeOps[M[_]](implicit MS : MonadState[M, Log]) { - def writeLine(line : String) : TeletypeT[M, Unit] = - FreeT.liftF[Teletype, M, Unit](WriteLine(line)) - def readLine(prompt : String) : TeletypeT[M, String] = - FreeT.liftF[Teletype, M, String](ReadLine(prompt)) - def log(s : String) : TeletypeT[M, Unit] = - FreeT.liftT[Teletype, M, Unit](MS.modify(s :: _)) -} - object TeletypeOps { - implicit def teleTypeOpsInstance[M[_]](implicit MS : MonadState[M, Log]) : TeletypeOps[M] = new TeletypeOps + def writeLine(line : String) : TeletypeT[TeletypeState, Unit] = + FreeT.liftF[Teletype, TeletypeState, Unit](WriteLine(line)) + def readLine(prompt : String) : TeletypeT[TeletypeState, String] = + FreeT.liftF[Teletype, TeletypeState, String](ReadLine(prompt)) + def log(s : String) : TeletypeT[TeletypeState, Unit] = + FreeT.liftT[Teletype, TeletypeState, Unit](State.modify(s :: _)) } -type TeletypeState[A] = State[List[String], A] - -def program(implicit TO : TeletypeOps[TeletypeState]) : TeletypeT[TeletypeState, Unit] = { +def program : TeletypeT[TeletypeState, Unit] = { for { - userSaid <- TO.readLine("what's up?!") - _ <- TO.log(s"user said : $userSaid") - _ <- TO.writeLine("thanks, see you soon!") + userSaid <- TeletypeOps.readLine("what's up?!") + _ <- TeletypeOps.log(s"user said : $userSaid") + _ <- TeletypeOps.writeLine("thanks, see you soon!") } yield () } diff --git a/free/src/main/scala/cats/free/Coyoneda.scala b/free/src/main/scala/cats/free/Coyoneda.scala index 4b22f7cbda2..5d9f110ca11 100644 --- a/free/src/main/scala/cats/free/Coyoneda.scala +++ b/free/src/main/scala/cats/free/Coyoneda.scala @@ -4,9 +4,9 @@ package free import cats.arrow.FunctionK /** - * The dual view of the Yoneda lemma. Also a free functor on `F`. + * The dual view of the Yoneda lemma. The free functor on `F`. * This is isomorphic to `F` as long as `F` itself is a functor. - * The homomorphism from `F[A]` to `Coyoneda[F,A]` exists even when + * The function from `F[A]` to `Coyoneda[F,A]` exists even when * `F` is not a functor. * Implemented using a List of functions for stack-safety. */ @@ -29,6 +29,10 @@ sealed abstract class Coyoneda[F[_], A] extends Serializable { self => /** Converts to `F[A]` given that `F` is a functor */ final def run(implicit F: Functor[F]): F[A] = F.map(fi)(k) + /** Converts to `F[A]` given that `F` is a functor */ + final def foldMap[G[_]](trans: F ~> G)(implicit G: Functor[G]): G[A] = + G.map(trans(fi))(k) + /** Converts to `Yoneda[F,A]` given that `F` is a functor */ final def toYoneda(implicit F: Functor[F]): Yoneda[F, A] = new Yoneda[F, A] { @@ -78,4 +82,5 @@ object Coyoneda { new Functor[Coyoneda[F, ?]] { def map[A, B](cfa: Coyoneda[F, A])(f: A => B): Coyoneda[F, B] = cfa map f } + } diff --git a/free/src/main/scala/cats/free/FreeApplicative.scala b/free/src/main/scala/cats/free/FreeApplicative.scala index aa0e0af77a3..ea9877ae53a 100644 --- a/free/src/main/scala/cats/free/FreeApplicative.scala +++ b/free/src/main/scala/cats/free/FreeApplicative.scala @@ -46,7 +46,7 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable } /** Interpret this algebra into a Monoid */ - final def analyze[M:Monoid](f: FunctionK[F, λ[α => M]]): M = + final def analyze[M: Monoid](f: FunctionK[F, λ[α => M]]): M = foldMap[Const[M, ?]]( λ[FunctionK[F, Const[M, ?]]](x => Const(f(x))) ).getConst @@ -83,4 +83,5 @@ object FreeApplicative { def pure[A](a: A): FA[S, A] = Pure(a) } } + } diff --git a/free/src/main/scala/cats/free/FreeT.scala b/free/src/main/scala/cats/free/FreeT.scala index b1f760056c5..bf559fe2614 100644 --- a/free/src/main/scala/cats/free/FreeT.scala +++ b/free/src/main/scala/cats/free/FreeT.scala @@ -182,21 +182,10 @@ object FreeT extends FreeTInstances { λ[FunctionK[FreeT[S, M, ?], M]](f => f.foldMap(fk)) } -private[free] sealed trait FreeTInstances3 { - implicit def catsFreeMonadStateForFreeT[S[_], M[_], E](implicit M1: MonadState[M, E]): MonadState[FreeT[S, M, ?], E] = - new MonadState[FreeT[S, M, ?], E] with FreeTMonad[S, M] { - override def M = implicitly - override def get = - FreeT.liftT(M1.get) - override def set(s: E) = - FreeT.liftT(M1.set(s)) - } -} - -private[free] sealed trait FreeTInstances2 extends FreeTInstances3 { +private[free] sealed trait FreeTInstances extends FreeTInstances0 { implicit def catsFreeMonadErrorForFreeT[S[_], M[_], E](implicit E: MonadError[M, E]): MonadError[FreeT[S, M, ?], E] = new MonadError[FreeT[S, M, ?], E] with FreeTMonad[S, M] { - override def M = implicitly + override def M = E override def handleErrorWith[A](fa: FreeT[S, M, A])(f: E => FreeT[S, M, A]) = FreeT.liftT[S, M, FreeT[S, M, A]](E.handleErrorWith(fa.toM)(f.andThen(_.toM)))(M).flatMap(identity) override def raiseError[A](e: E) = @@ -204,39 +193,35 @@ private[free] sealed trait FreeTInstances2 extends FreeTInstances3 { } } +private[free] sealed trait FreeTInstances0 extends FreeTInstances1 { + implicit def catsFreeMonadForFreeT[S[_], M[_]](implicit M0: Applicative[M]): Monad[FreeT[S, M, ?]] = + new FreeTMonad[S, M] { + def M = M0 + } +} + private[free] sealed trait FreeTInstances1 extends FreeTInstances2 { implicit def catsFreeFlatMapForFreeT[S[_], M[_]](implicit M0: Applicative[M]): FlatMap[FreeT[S, M, ?]] = new FreeTFlatMap[S, M] { implicit def M: Applicative[M] = M0 } - - implicit def catsFreeMonadTransForFreeT[S[_]]: MonadTrans[FreeT[S, ?[_], ?]] = - new MonadTrans[FreeT[S, ?[_], ?]] { - override def liftT[M[_]: Monad, A](ma: M[A]): FreeT[S, M, A] = - FreeT.liftT(ma) - } } -private[free] sealed trait FreeTInstances0 extends FreeTInstances1 { - implicit def catsFreeMonadForFreeT[S[_], M[_]](implicit M0: Applicative[M]): Monad[FreeT[S, M, ?]] = - new FreeTMonad[S, M] { - def M = M0 - } +private[free] sealed trait FreeTInstances2 extends FreeTInstances3 { + implicit def catsFreeAlternativeForFreeT[S[_], M[_]: Alternative: Monad]: Alternative[FreeT[S, M, ?]] = + new Alternative[FreeT[S, M, ?]] with FreeTMonad[S, M] with FreeTMonoidK[S, M] { + override def M = Alternative[M] + override def M1 = Alternative[M] - implicit def catsFreeCombineForFreeT[S[_], M[_]: Applicative: SemigroupK]: SemigroupK[FreeT[S, M, ?]] = - new FreeTCombine[S, M] { - override def M = implicitly - override def M1 = implicitly + def ap[A, B](fa: FreeT[S, M, A])(ff: FreeT[S, M, A => B]): FreeT[S, M, B] = fa.flatMap(a => ff.map(_(a))(M)) } } -private[free] sealed trait FreeTInstances extends FreeTInstances0 { - implicit def catsFreeMonadCombineForFreeT[S[_], M[_]: Alternative]: MonadCombine[FreeT[S, M, ?]] = - new MonadCombine[FreeT[S, M, ?]] with FreeTCombine[S, M] with FreeTMonad[S, M] { - override def M = implicitly - override def M1 = implicitly - - override def empty[A] = FreeT.liftT[S, M, A](MonoidK[M].empty[A])(M) +private[free] sealed trait FreeTInstances3 { + implicit def catsFreeSemigroupKForFreeT[S[_], M[_]: Applicative: SemigroupK]: SemigroupK[FreeT[S, M, ?]] = + new FreeTSemigroupK[S, M] { + override def M = Applicative[M] + override def M1 = SemigroupK[M] } } @@ -256,9 +241,16 @@ private[free] sealed trait FreeTMonad[S[_], M[_]] extends Monad[FreeT[S, M, ?]] FreeT.pure[S, M, A](a) } -private[free] sealed trait FreeTCombine[S[_], M[_]] extends SemigroupK[FreeT[S, M, ?]] { +private[free] sealed trait FreeTMonoidK[S[_], M[_]] extends MonoidK[FreeT[S, M, ?]] with FreeTSemigroupK[S, M] { + implicit def M: Applicative[M] + def M1: MonoidK[M] + override final def empty[A]: FreeT[S, M, A] = FreeT.liftT[S, M, A](M1.empty[A])(M) +} + +private[free] sealed trait FreeTSemigroupK[S[_], M[_]] extends SemigroupK[FreeT[S, M, ?]] { implicit def M: Applicative[M] def M1: SemigroupK[M] override final def combineK[A](a: FreeT[S, M, A], b: FreeT[S, M, A]): FreeT[S, M, A] = FreeT.liftT(M1.combineK(a.toM, b.toM))(M).flatMap(identity) } + diff --git a/free/src/main/scala/cats/free/Yoneda.scala b/free/src/main/scala/cats/free/Yoneda.scala index 7f2b54438f8..2e9e468081c 100644 --- a/free/src/main/scala/cats/free/Yoneda.scala +++ b/free/src/main/scala/cats/free/Yoneda.scala @@ -2,9 +2,9 @@ package cats package free /** - * The free functor generated by `F`. The Yoneda lemma says that + * The cofree functor for `F`. The Yoneda lemma says that * `Yoneda[F,A]` is isomorphic to `F[A]` for any functor `F`. - * The homomorphism from `Yoneda[F,A]` to `F[A]` exists even when + * The function from `Yoneda[F, A]` to `F[A]` exists even when * we have forgotten that `F` is a functor. * Can be seen as a partially applied `map` for the functor `F`. */ diff --git a/free/src/test/scala/cats/free/FreeTTests.scala b/free/src/test/scala/cats/free/FreeTTests.scala index a05f3d2e89d..a5f2f30f1ea 100644 --- a/free/src/test/scala/cats/free/FreeTTests.scala +++ b/free/src/test/scala/cats/free/FreeTTests.scala @@ -5,9 +5,9 @@ import cats._ import cats.arrow.FunctionK import cats.data._ import cats.laws.discipline._ +import cats.laws.discipline.arbitrary._ import cats.tests.CatsSuite import cats.instances.option._ -import cats.laws.discipline.arbitrary.catsLawArbitraryForState import org.scalacheck.{Arbitrary, Gen, Cogen} class FreeTTests extends CatsSuite { @@ -27,15 +27,15 @@ class FreeTTests extends CatsSuite { } { - implicit val freeTSemigroupK: SemigroupK[FreeTOption] = FreeT.catsFreeCombineForFreeT[Option, Option] + implicit val freeTSemigroupK: SemigroupK[FreeTOption] = FreeT.catsFreeSemigroupKForFreeT[Option, Option] checkAll("FreeT[Option, Option, Int]", SemigroupKTests[FreeTOption].semigroupK[Int]) checkAll("SemigroupK[FreeT[Option, Option, ?]]", SerializableTests.serializable(SemigroupK[FreeTOption])) } { - implicit val freeTCombine: MonadCombine[FreeTOption] = FreeT.catsFreeMonadCombineForFreeT[Option, Option] - checkAll("FreeT[Option, Option, Int]", MonadCombineTests[FreeTOption].monadCombine[Int, Int, Int]) - checkAll("MonadCombine[FreeT[Option, Option, ?]]", SerializableTests.serializable(MonadCombine[FreeTOption])) + implicit val freeTAlternative: Alternative[FreeTOption] = FreeT.catsFreeAlternativeForFreeT[Option, Option] + checkAll("FreeT[Option, Option, Int]", AlternativeTests[FreeTOption].alternative[Int, Int, Int]) + checkAll("Alternative[FreeT[Option, Option, ?]]", SerializableTests.serializable(Alternative[FreeTOption])) } { @@ -44,17 +44,6 @@ class FreeTTests extends CatsSuite { checkAll("MonadError[FreeT[Option, Option, ?], Unit]", SerializableTests.serializable(MonadError[FreeTOption, Unit])) } - { - import StateT._ - checkAll("FreeT[State[Int, ?], State[Int, ?], Int]", MonadStateTests[FreeTState, Int].monadState[Int, Int, Int]) - checkAll("MonadState[FreeT[State[Int, ?], State[Int, ?], ?], Int]", SerializableTests.serializable(MonadState[FreeTState, Int])) - } - - { - checkAll("FreeT[Option, Option, Int]]", MonadTransTests[FreeT[Option, ?[_], ?]].monadTrans[Option, Int, Int]) - checkAll("MonadTrans[FreeT[Option, ?[_], Int, ?]]", SerializableTests.serializable(MonadTrans[FreeT[Option, ?[_], ?]])) - } - test("FlatMap stack safety tested with 50k flatMaps") { val expected = Applicative[FreeTOption].pure(()) val result = diff --git a/laws/src/main/scala/cats/laws/FunctorFilterLaws.scala b/laws/src/main/scala/cats/laws/FunctorFilterLaws.scala deleted file mode 100644 index d79de5dadcb..00000000000 --- a/laws/src/main/scala/cats/laws/FunctorFilterLaws.scala +++ /dev/null @@ -1,35 +0,0 @@ -package cats -package laws - -import cats.implicits._ - -trait FunctorFilterLaws[F[_]] extends FunctorLaws[F] { - implicit override def F: FunctorFilter[F] - - def mapFilterComposition[A, B, C]( - fa: F[A], - f: A => Option[B], - g: B => Option[C] - ): IsEq[F[C]] = { - - val lhs: F[C] = fa.mapFilter(f).mapFilter(g) - val rhs: F[C] = fa.mapFilter(a => f(a).flatMap(g)) - lhs <-> rhs - } - - /** - * Combined with the functor identity law, this implies a `mapFilter` identity - * law (when `f` is the identity function). - */ - def mapFilterMapConsistency[A, B]( - fa: F[A], - f: A => B - ): IsEq[F[B]] = { - fa.mapFilter(f andThen (_.some)) <-> fa.map(f) - } -} - -object FunctorFilterLaws { - def apply[F[_]](implicit ev: FunctorFilter[F]): FunctorFilterLaws[F] = - new FunctorFilterLaws[F] { def F: FunctorFilter[F] = ev } -} diff --git a/laws/src/main/scala/cats/laws/MonadCombineLaws.scala b/laws/src/main/scala/cats/laws/MonadCombineLaws.scala deleted file mode 100644 index 689466a2aff..00000000000 --- a/laws/src/main/scala/cats/laws/MonadCombineLaws.scala +++ /dev/null @@ -1,27 +0,0 @@ -package cats -package laws - -// import cats.syntax.all._ - -/** - * Laws that must be obeyed by any `MonadCombine`. - */ -trait MonadCombineLaws[F[_]] extends MonadFilterLaws[F] with AlternativeLaws[F] { - implicit override def F: MonadCombine[F] - - // the left distributivity law does not hold for things like - // MonadCombine[Option]; here's a counter-example: - // - // def f(x: Int): Option[Int] = if (x == 0) None else Some(x) - // val a = Option(0) - // val b = Option(1) - // (a <+> b).flatMap(f) != (a.flatMap(f) <+> b.flatMap(f)) - // - // def monadCombineLeftDistributivity[A, B](fa: F[A], fa2: F[A], f: A => F[B]): IsEq[F[B]] = - // F.combineK(fa, fa2).flatMap(f) <-> F.combineK(fa flatMap f, fa2 flatMap f) -} - -object MonadCombineLaws { - def apply[F[_]](implicit ev: MonadCombine[F]): MonadCombineLaws[F] = - new MonadCombineLaws[F] { def F: MonadCombine[F] = ev } -} diff --git a/laws/src/main/scala/cats/laws/MonadFilterLaws.scala b/laws/src/main/scala/cats/laws/MonadFilterLaws.scala deleted file mode 100644 index 9116df2bba7..00000000000 --- a/laws/src/main/scala/cats/laws/MonadFilterLaws.scala +++ /dev/null @@ -1,25 +0,0 @@ -package cats -package laws - -import cats.syntax.all._ - -/** - * Laws that must be obeyed by any `MonadFilter`. - */ -trait MonadFilterLaws[F[_]] extends MonadLaws[F] with FunctorFilterLaws[F] { - implicit override def F: MonadFilter[F] - - def monadFilterLeftEmpty[A, B](f: A => F[B]): IsEq[F[B]] = - F.empty[A].flatMap(f) <-> F.empty[B] - - def monadFilterRightEmpty[A, B](fa: F[A]): IsEq[F[B]] = - fa.flatMap(_ => F.empty[B]) <-> F.empty[B] - - def monadFilterConsistency[A, B](fa: F[A], f: A => Boolean): IsEq[F[A]] = - fa.filter(f) <-> fa.flatMap(a => if (f(a)) F.pure(a) else F.empty) -} - -object MonadFilterLaws { - def apply[F[_]](implicit ev: MonadFilter[F]): MonadFilterLaws[F] = - new MonadFilterLaws[F] { def F: MonadFilter[F] = ev } -} diff --git a/laws/src/main/scala/cats/laws/MonadReaderLaws.scala b/laws/src/main/scala/cats/laws/MonadReaderLaws.scala deleted file mode 100644 index 69c5652379e..00000000000 --- a/laws/src/main/scala/cats/laws/MonadReaderLaws.scala +++ /dev/null @@ -1,27 +0,0 @@ -package cats -package laws - -// Taken from http://functorial.com/psc-pages/docs/Control/Monad/Reader/Class/index.html -trait MonadReaderLaws[F[_], R] extends MonadLaws[F] { - implicit override def F: MonadReader[F, R] - - val monadReaderAskIdempotent: IsEq[F[R]] = - F.flatMap(F.ask)(_ => F.ask) <-> F.ask - - def monadReaderLocalAsk(f: R => R): IsEq[F[R]] = - F.local(f)(F.ask) <-> F.map(F.ask)(f) - - def monadReaderLocalPure[A](a: A, f: R => R): IsEq[F[A]] = - F.local(f)(F.pure(a)) <-> F.pure(a) - - def monadReaderLocalFlatMap[A, B](fra: F[A], f: A => F[B], g: R => R): IsEq[F[B]] = - F.local(g)(F.flatMap(fra)(f)) <-> F.flatMap(F.local(g)(fra))(a => F.local(g)(f(a))) - - def monadReaderReaderAsk[A](f: R => A): IsEq[F[A]] = - F.reader(f) <-> F.map(F.ask)(f) -} - -object MonadReaderLaws { - def apply[F[_], R](implicit FR: MonadReader[F, R]): MonadReaderLaws[F, R] = - new MonadReaderLaws[F, R] { def F: MonadReader[F, R] = FR } -} diff --git a/laws/src/main/scala/cats/laws/MonadStateLaws.scala b/laws/src/main/scala/cats/laws/MonadStateLaws.scala deleted file mode 100644 index 99eac2080ab..00000000000 --- a/laws/src/main/scala/cats/laws/MonadStateLaws.scala +++ /dev/null @@ -1,24 +0,0 @@ -package cats -package laws - -// Taken from http://functorial.com/psc-pages/docs/Control/Monad/State/Class/index.html -trait MonadStateLaws[F[_], S] extends MonadLaws[F] { - implicit override def F: MonadState[F, S] - - val monadStateGetIdempotent: IsEq[F[S]] = - F.flatMap(F.get)(_ => F.get) <-> F.get - - def monadStateSetTwice(s: S, t: S): IsEq[F[Unit]] = - F.flatMap(F.set(s))(_ => F.set(t)) <-> F.set(t) - - def monadStateSetGet(s: S): IsEq[F[S]] = - F.flatMap(F.set(s))(_ => F.get) <-> F.flatMap(F.set(s))(_ => F.pure(s)) - - val monadStateGetSet: IsEq[F[Unit]] = - F.flatMap(F.get)(F.set) <-> F.pure(()) -} - -object MonadStateLaws { - def apply[F[_], S](implicit FS: MonadState[F, S]): MonadStateLaws[F, S] = - new MonadStateLaws[F, S] { def F: MonadState[F, S] = FS } -} diff --git a/laws/src/main/scala/cats/laws/MonadTransLaws.scala b/laws/src/main/scala/cats/laws/MonadTransLaws.scala deleted file mode 100644 index d361af84381..00000000000 --- a/laws/src/main/scala/cats/laws/MonadTransLaws.scala +++ /dev/null @@ -1,17 +0,0 @@ -package cats -package laws - -trait MonadTransLaws[MT[_[_], _]] { - implicit def MT: MonadTrans[MT] - - def identity[G[_], A](a: A)(implicit G: Monad[G], MTM: Monad[MT[G, ?]]): IsEq[MT[G, A]] = - MT.liftT(G.pure(a)) <-> MTM.pure(a) - - def composition[G[_], A, B](ga: G[A], f: A => G[B])(implicit G: Monad[G], MTM: Monad[MT[G, ?]]): IsEq[MT[G, B]] = - MT.liftT(G.flatMap(ga)(f)) <-> MTM.flatMap(MT.liftT(ga))(a => MT.liftT(f(a))) -} - -object MonadTransLaws { - def apply[MT[_[_], _]](implicit ev: MonadTrans[MT]): MonadTransLaws[MT] = - new MonadTransLaws[MT] { def MT: MonadTrans[MT] = ev } -} diff --git a/laws/src/main/scala/cats/laws/MonadWriterLaws.scala b/laws/src/main/scala/cats/laws/MonadWriterLaws.scala deleted file mode 100644 index 07c55eb656b..00000000000 --- a/laws/src/main/scala/cats/laws/MonadWriterLaws.scala +++ /dev/null @@ -1,23 +0,0 @@ -package cats -package laws - -trait MonadWriterLaws[F[_], W] extends MonadLaws[F] { - implicit override def F: MonadWriter[F, W] - - def monadWriterWriterPure[A](a: A)(implicit W: Monoid[W]): IsEq[F[A]] = - F.writer((W.empty, a)) <-> F.pure(a) - - def monadWriterTellFusion(x: W, y: W)(implicit W: Monoid[W]): IsEq[F[Unit]] = - F.flatMap(F.tell(x))(_ => F.tell(y)) <-> F.tell(W.combine(x, y)) - - def monadWriterListenPure[A](a: A)(implicit W: Monoid[W]): IsEq[F[(W, A)]] = - F.listen(F.pure(a)) <-> F.pure((W.empty, a)) - - def monadWriterListenWriter[A](aw: (W, A)): IsEq[F[(W, A)]] = - F.listen(F.writer(aw)) <-> F.map(F.tell(aw._1))(_ => aw) -} - -object MonadWriterLaws { - def apply[F[_], W](implicit FW: MonadWriter[F, W]): MonadWriterLaws[F, W] = - new MonadWriterLaws[F, W] { def F: MonadWriter[F, W] = FW } -} diff --git a/laws/src/main/scala/cats/laws/TraverseFilterLaws.scala b/laws/src/main/scala/cats/laws/TraverseFilterLaws.scala deleted file mode 100644 index 8620d9b926a..00000000000 --- a/laws/src/main/scala/cats/laws/TraverseFilterLaws.scala +++ /dev/null @@ -1,33 +0,0 @@ -package cats -package laws - -import cats.data.Nested -import cats.implicits._ - -trait TraverseFilterLaws[F[_]] extends TraverseLaws[F] with FunctorFilterLaws[F] { - implicit override def F: TraverseFilter[F] - - def traverseFilterIdentity[G[_]:Applicative, A](fa: F[A]): IsEq[G[F[A]]] = { - fa.traverseFilter(_.some.pure[G]) <-> fa.pure[G] - } - - def traverseFilterComposition[A, B, C, M[_], N[_]]( - fa: F[A], - f: A => M[Option[B]], - g: B => N[Option[C]] - )(implicit - M: Applicative[M], - N: Applicative[N] - ): IsEq[Nested[M, N, F[C]]] = { - - val lhs: Nested[M, N, F[C]] = Nested(fa.traverseFilter(f).map(_.traverseFilter(g))) - val rhs: Nested[M, N, F[C]] = fa.traverseFilter[Nested[M, N, ?], C](a => - Nested(f(a).map(_.traverseFilter(g)))) - lhs <-> rhs - } -} - -object TraverseFilterLaws { - def apply[F[_]](implicit ev: TraverseFilter[F]): TraverseFilterLaws[F] = - new TraverseFilterLaws[F] { def F: TraverseFilter[F] = ev } -} diff --git a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala index 1cdb684e8da..9ece157e12c 100644 --- a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala +++ b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala @@ -159,7 +159,6 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawArbitraryForReader[A: Arbitrary: Cogen, B: Arbitrary]: Arbitrary[Reader[A, B]] = catsLawsArbitraryForKleisli[Id, A, B] - implicit def catsLawArbitraryForCokleisliId[A: Arbitrary: Cogen, B: Arbitrary]: Arbitrary[Cokleisli[Id, A, B]] = catsLawsArbitraryForCokleisli[Id, A, B] diff --git a/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala b/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala deleted file mode 100644 index 813e1c6fd0b..00000000000 --- a/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala +++ /dev/null @@ -1,33 +0,0 @@ -package cats -package laws -package discipline - -import org.scalacheck.{Arbitrary, Cogen, Prop} -import Prop._ - -trait FunctorFilterTests[F[_]] extends FunctorTests[F] { - def laws: FunctorFilterLaws[F] - - def functorFilter[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - ArbAOB: Arbitrary[A => Option[B]], - ArbBOC: Arbitrary[B => Option[C]], - ArbAB: Arbitrary[A => C], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFC: Eq[F[C]] - ): RuleSet = { - new DefaultRuleSet( - name = "functorFilter", - parent = Some(functor[A, B, C]), - "mapFilter composition" -> forAll(laws.mapFilterComposition[A, B, C] _), - "mapFilter map consistency" -> forAll(laws.mapFilterMapConsistency[A, C] _)) - } -} - -object FunctorFilterTests { - def apply[F[_]: FunctorFilter]: FunctorFilterTests[F] = - new FunctorFilterTests[F] { def laws: FunctorFilterLaws[F] = FunctorFilterLaws[F] } -} diff --git a/laws/src/main/scala/cats/laws/discipline/MonadCombineTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadCombineTests.scala deleted file mode 100644 index 5174ad82fa8..00000000000 --- a/laws/src/main/scala/cats/laws/discipline/MonadCombineTests.scala +++ /dev/null @@ -1,45 +0,0 @@ -package cats -package laws -package discipline - -import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.{Arbitrary, Cogen, Prop} -// import Prop._ - -trait MonadCombineTests[F[_]] extends MonadFilterTests[F] with AlternativeTests[F] { - def laws: MonadCombineLaws[F] - - def monadCombine[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 = "monadCombine" - def bases: Seq[(String, RuleSet)] = Nil - def parents: Seq[RuleSet] = Seq(monadFilter[A, B, C], alternative[A, B, C]) - def props: Seq[(String, Prop)] = Nil - // def props: Seq[(String, Prop)] = Seq( - // "monadCombine left distributivity" -> forAll(laws.monadCombineLeftDistributivity[A, B] _) - // ) - } - } -} - -object MonadCombineTests { - def apply[F[_]: MonadCombine]: MonadCombineTests[F] = - new MonadCombineTests[F] { - def laws: MonadCombineLaws[F] = MonadCombineLaws[F] - } -} diff --git a/laws/src/main/scala/cats/laws/discipline/MonadFilterTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadFilterTests.scala deleted file mode 100644 index fee5fa4676d..00000000000 --- a/laws/src/main/scala/cats/laws/discipline/MonadFilterTests.scala +++ /dev/null @@ -1,46 +0,0 @@ -package cats -package laws -package discipline - -import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.{Arbitrary, Cogen, Prop} -import Prop._ - -trait MonadFilterTests[F[_]] extends MonadTests[F] with FunctorFilterTests[F] { - def laws: MonadFilterLaws[F] - - def monadFilter[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 = "monadFilter" - def bases: Seq[(String, RuleSet)] = Nil - def parents: Seq[RuleSet] = Seq(monad[A, B, C], functorFilter[A, B, C]) - def props: Seq[(String, Prop)] = Seq( - "monadFilter left empty" -> forAll(laws.monadFilterLeftEmpty[A, B] _), - "monadFilter right empty" -> forAll(laws.monadFilterRightEmpty[A, B] _), - "monadFilter consistency" -> forAll(laws.monadFilterConsistency[A, B] _) - ) - } - } -} - -object MonadFilterTests { - def apply[F[_]: MonadFilter]: MonadFilterTests[F] = - new MonadFilterTests[F] { - def laws: MonadFilterLaws[F] = MonadFilterLaws[F] - } -} diff --git a/laws/src/main/scala/cats/laws/discipline/MonadReaderTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadReaderTests.scala deleted file mode 100644 index eda00a53a72..00000000000 --- a/laws/src/main/scala/cats/laws/discipline/MonadReaderTests.scala +++ /dev/null @@ -1,51 +0,0 @@ -package cats -package laws -package discipline - -import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.{Arbitrary, Cogen, Prop} -import org.scalacheck.Prop.forAll - -trait MonadReaderTests[F[_], R] extends MonadTests[F] { - def laws: MonadReaderLaws[F, R] - - def monadReader[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]], - ArbR: Arbitrary[R], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - CogenR: Cogen[R], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFR: Eq[F[R]], - EqFABC: Eq[F[(A, B, C)]], - EqFInt: Eq[F[Int]], - iso: Isomorphisms[F] - ): RuleSet = { - new RuleSet { - def name: String = "monadReader" - def bases: Seq[(String, RuleSet)] = Nil - def parents: Seq[RuleSet] = Seq(monad[A, B, C]) - def props: Seq[(String, Prop)] = Seq( - "monadReader ask idempotent" -> laws.monadReaderAskIdempotent, - "monadReader local ask" -> forAll(laws.monadReaderLocalAsk _), - "monadReader local pure" -> forAll(laws.monadReaderLocalPure[A] _), - "monadReader local flatMap" -> forAll(laws.monadReaderLocalFlatMap[A, B] _), - "monadReader reader ask" -> forAll(laws.monadReaderReaderAsk[A] _) - ) - } - } -} - -object MonadReaderTests { - def apply[F[_], R](implicit FR: MonadReader[F, R]): MonadReaderTests[F, R] = - new MonadReaderTests[F, R] { - def laws: MonadReaderLaws[F, R] = MonadReaderLaws[F, R] - } -} diff --git a/laws/src/main/scala/cats/laws/discipline/MonadStateTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadStateTests.scala deleted file mode 100644 index 060b14a44bf..00000000000 --- a/laws/src/main/scala/cats/laws/discipline/MonadStateTests.scala +++ /dev/null @@ -1,52 +0,0 @@ -package cats -package laws -package discipline - -import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.{Arbitrary, Cogen, Prop} -import org.scalacheck.Prop.forAll - -trait MonadStateTests[F[_], S] extends MonadTests[F] { - def laws: MonadStateLaws[F, S] - - def monadState[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]], - ArbS: Arbitrary[S], - ArbFS: Arbitrary[F[S]], - ArbFUnit: Arbitrary[F[Unit]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFUnit: Eq[F[Unit]], - EqFS: Eq[F[S]], - EqFABC: Eq[F[(A, B, C)]], - EqFInt: Eq[F[Int]], - iso: Isomorphisms[F] - ): RuleSet = { - new RuleSet { - def name: String = "monadState" - def bases: Seq[(String, RuleSet)] = Nil - def parents: Seq[RuleSet] = Seq(monad[A, B, C]) - def props: Seq[(String, Prop)] = Seq( - "monadState get idempotent" -> laws.monadStateGetIdempotent, - "monadState set twice" -> forAll(laws.monadStateSetTwice _), - "monadState set get" -> forAll(laws.monadStateSetGet _), - "monadState get set" -> laws.monadStateGetSet - ) - } - } -} - -object MonadStateTests { - def apply[F[_], S](implicit FS: MonadState[F, S]): MonadStateTests[F, S] = - new MonadStateTests[F, S] { - def laws: MonadStateLaws[F, S] = MonadStateLaws[F, S] - } -} diff --git a/laws/src/main/scala/cats/laws/discipline/MonadTransTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadTransTests.scala deleted file mode 100644 index c20d1244659..00000000000 --- a/laws/src/main/scala/cats/laws/discipline/MonadTransTests.scala +++ /dev/null @@ -1,36 +0,0 @@ -package cats -package laws -package discipline - -import org.scalacheck.{Arbitrary, Cogen, Prop} -import org.typelevel.discipline.Laws -import Prop._ - -trait MonadTransTests[MT[_[_], _]] extends Laws { - def laws: MonadTransLaws[MT] - - def monadTrans[G[_]: Monad, A: Arbitrary: Eq, B: Eq](implicit - MonadMTG: Monad[MT[G, ?]], - ArbGA: Arbitrary[G[A]], - ArbGB: Arbitrary[G[B]], - CogenA: Cogen[A], - EqGA: Eq[G[A]], - EqGB: Eq[G[B]], - EqMTGA: Eq[MT[G, A]], - EqMTGB: Eq[MT[G, B]] - ): RuleSet = { - new DefaultRuleSet( - name = "monadTrans", - parent = None, - "monadTrans identity" -> forAll(laws.identity[G, A] _), - "monadTrans composition" -> forAll(laws.composition[G, A, B] _) - ) - } -} - -object MonadTransTests { - def apply[MT[_[_], _]: MonadTrans]: MonadTransTests[MT] = - new MonadTransTests[MT] { - def laws: MonadTransLaws[MT] = MonadTransLaws[MT] - } -} diff --git a/laws/src/main/scala/cats/laws/discipline/MonadWriterTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadWriterTests.scala deleted file mode 100644 index 888f9921066..00000000000 --- a/laws/src/main/scala/cats/laws/discipline/MonadWriterTests.scala +++ /dev/null @@ -1,50 +0,0 @@ -package cats -package laws -package discipline - -import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.{Arbitrary, Cogen} -import org.scalacheck.Prop.forAll - -trait MonadWriterTests[F[_], W] extends MonadTests[F] { - def laws: MonadWriterLaws[F, W] - - def monadWriter[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]], - EqFAW: Eq[F[(W, A)]], - EqFB: Eq[F[B]], - 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] - ): RuleSet = - new RuleSet { - def name = "monadWriter" - def bases = Nil - def parents = Seq(monad[A, B, C]) - def props = Seq( - "monadWriter writer pure" -> forAll(laws.monadWriterWriterPure[A] _), - "monadWriter tell fusion" -> forAll(laws.monadWriterTellFusion _), - "monadWriter listen pure" -> forAll(laws.monadWriterListenPure[A] _), - "monadWriter listen writer" -> forAll(laws.monadWriterListenWriter[A] _) - ) - } -} - -object MonadWriterTests { - def apply[F[_], W](implicit FW: MonadWriter[F, W]): MonadWriterTests[F, W] = - new MonadWriterTests[F, W] { - def laws: MonadWriterLaws[F, W] = MonadWriterLaws[F, W] - } -} diff --git a/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala b/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala deleted file mode 100644 index 0f560535ca5..00000000000 --- a/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala +++ /dev/null @@ -1,47 +0,0 @@ -package cats -package laws -package discipline - -import org.scalacheck.{Arbitrary, Cogen, Prop} -import Prop._ - -trait TraverseFilterTests[F[_]] extends TraverseTests[F] with FunctorFilterTests[F] { - def laws: TraverseFilterLaws[F] - - def traverseFilter[A: Arbitrary, B: Arbitrary, C: Arbitrary, M: Arbitrary, X[_]: Applicative, Y[_]: Applicative](implicit - ArbFA: Arbitrary[F[A]], - ArbXB: Arbitrary[X[B]], - ArbYB: Arbitrary[Y[B]], - ArbYC: Arbitrary[Y[C]], - ArbAXOB: Arbitrary[A => X[Option[B]]], - ArbBYOC: Arbitrary[B => Y[Option[C]]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - CogenM: Cogen[M], - M: Monoid[M], - EqFA: Eq[F[A]], - EqFC: Eq[F[C]], - EqM: Eq[M], - EqXYFC: Eq[X[Y[F[C]]]], - EqXFA: Eq[X[F[A]]], - EqXFB: Eq[X[F[B]]], - EqYFB: Eq[Y[F[B]]], - EqOptionA: Eq[Option[A]] - ): RuleSet = { - new RuleSet { - def name: String = "traverseFilter" - def bases: Seq[(String, RuleSet)] = Nil - def parents: Seq[RuleSet] = Seq(traverse[A, B, C, M, X, Y], functorFilter[A, B, C]) - def props: Seq[(String, Prop)] = Seq( - "traverseFilter identity" -> forAll(laws.traverseFilterIdentity[X, A] _), - "traverseFilter composition" -> forAll(laws.traverseFilterComposition[A, B, C, X, Y] _) - ) - } - } -} - -object TraverseFilterTests { - def apply[F[_]: TraverseFilter]: TraverseFilterTests[F] = - new TraverseFilterTests[F] { def laws: TraverseFilterLaws[F] = TraverseFilterLaws[F] } -} diff --git a/tests/src/test/scala/cats/tests/ApplicativeErrorTests.scala b/tests/src/test/scala/cats/tests/ApplicativeErrorCheck.scala similarity index 100% rename from tests/src/test/scala/cats/tests/ApplicativeErrorTests.scala rename to tests/src/test/scala/cats/tests/ApplicativeErrorCheck.scala diff --git a/tests/src/test/scala/cats/tests/ApplicativeTests.scala b/tests/src/test/scala/cats/tests/ApplicativeTests.scala index 1cb029df3f6..c5c11c2e7c7 100644 --- a/tests/src/test/scala/cats/tests/ApplicativeTests.scala +++ b/tests/src/test/scala/cats/tests/ApplicativeTests.scala @@ -4,7 +4,7 @@ package tests import cats.Applicative -class ApplicativeTests extends CatsSuite { +class ApplicativeCheck extends CatsSuite { test("Applicative#traverse is equivalent to Traverse#traverse") { val f: (Int) => Option[Int] = x => Some(x + 1) diff --git a/tests/src/test/scala/cats/tests/ConstTests.scala b/tests/src/test/scala/cats/tests/ConstTests.scala index c79cbeb0a00..9b9b8d8541f 100644 --- a/tests/src/test/scala/cats/tests/ConstTests.scala +++ b/tests/src/test/scala/cats/tests/ConstTests.scala @@ -10,7 +10,7 @@ import cats.laws.discipline.arbitrary._ class ConstTests extends CatsSuite { - implicit val iso = CartesianTests.Isomorphisms.invariant[Const[String, ?]](Const.catsDataTraverseFilterForConst) + implicit val iso = CartesianTests.Isomorphisms.invariant[Const[String, ?]](Const.catsDataTraverseForConst) checkAll("Const[String, Int]", CartesianTests[Const[String, ?]].cartesian[Int, Int, Int]) checkAll("Cartesian[Const[String, ?]]", SerializableTests.serializable(Cartesian[Const[String, ?]])) @@ -18,8 +18,8 @@ class ConstTests extends CatsSuite { checkAll("Const[String, Int]", ApplicativeTests[Const[String, ?]].applicative[Int, Int, Int]) checkAll("Applicative[Const[String, ?]]", SerializableTests.serializable(Applicative[Const[String, ?]])) - checkAll("Const[String, Int] with Option", TraverseFilterTests[Const[String, ?]].traverseFilter[Int, Int, Int, Int, Option, Option]) - checkAll("TraverseFilter[Const[String, ?]]", SerializableTests.serializable(TraverseFilter[Const[String, ?]])) + checkAll("Const[String, Int] with Option", TraverseTests[Const[String, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[Const[String, ?]]", SerializableTests.serializable(Traverse[Const[String, ?]])) // Get Apply[Const[C : Semigroup, ?]], not Applicative[Const[C : Monoid, ?]] { diff --git a/tests/src/test/scala/cats/tests/EitherTTests.scala b/tests/src/test/scala/cats/tests/EitherTTests.scala index addd08f9197..4ca7575a741 100644 --- a/tests/src/test/scala/cats/tests/EitherTTests.scala +++ b/tests/src/test/scala/cats/tests/EitherTTests.scala @@ -53,12 +53,9 @@ class EitherTTests extends CatsSuite { Functor[EitherT[ListWrapper, String, ?]] Applicative[EitherT[ListWrapper, String, ?]] Monad[EitherT[ListWrapper, String, ?]] - MonadTrans[EitherT[?[_], String, ?]] checkAll("EitherT[ListWrapper, String, Int]", MonadErrorTests[EitherT[ListWrapper, String, ?], String].monadError[Int, Int, Int]) checkAll("MonadError[EitherT[List, ?, ?]]", SerializableTests.serializable(MonadError[EitherT[ListWrapper, String, ?], String])) - checkAll("EitherT[ListWrapper, String, Int]]", MonadTransTests[EitherT[?[_], String, ?]].monadTrans[ListWrapper, Int, Int]) - checkAll("MonadTrans[EitherT[?[_], String, ?]]", SerializableTests.serializable(MonadTrans[EitherT[?[_], String, ?]])) } { diff --git a/tests/src/test/scala/cats/tests/FunctionTests.scala b/tests/src/test/scala/cats/tests/FunctionTests.scala index 4c893160b3b..6d12d52486d 100644 --- a/tests/src/test/scala/cats/tests/FunctionTests.scala +++ b/tests/src/test/scala/cats/tests/FunctionTests.scala @@ -24,8 +24,8 @@ class FunctionTests extends CatsSuite { checkAll("Function1[Int, Int]", CartesianTests[Function1[Int, ?]].cartesian[Int, Int, Int]) checkAll("Cartesian[Function1[Int, ?]]", SerializableTests.serializable(Cartesian[Function1[Int, ?]])) - checkAll("Function1[Int, Int]", MonadReaderTests[Int => ?, Int].monadReader[Int, Int, Int]) - checkAll("MonadReader[Int => ?, Int]", SerializableTests.serializable(MonadReader[Int => ?, Int])) + checkAll("Function1[Int, Int]", MonadTests[Int => ?].monad[Int, Int, Int]) + checkAll("Monad[Int => ?]", SerializableTests.serializable(Monad[Int => ?])) checkAll("Function1[Int, Int]", CommutativeArrowTests[Function1].commutativeArrow[Int, Int, Int, Int, Int, Int]) checkAll("Arrow[Function1]", SerializableTests.serializable(CommutativeArrow[Function1])) diff --git a/tests/src/test/scala/cats/tests/IdTTests.scala b/tests/src/test/scala/cats/tests/IdTTests.scala index e362eec7a1e..24a0daf25c9 100644 --- a/tests/src/test/scala/cats/tests/IdTTests.scala +++ b/tests/src/test/scala/cats/tests/IdTTests.scala @@ -57,9 +57,6 @@ class IdTTests extends CatsSuite { checkAll("IdT[ListWrapper, Int]", MonadTests[IdT[ListWrapper, ?]].monad[Int, Int, Int]) checkAll("Monad[IdT[ListWrapper, ?]]", SerializableTests.serializable(Monad[IdT[ListWrapper, ?]])) - - checkAll("IdT[ListWrapper, Int]", MonadTransTests[IdT].monadTrans[ListWrapper, Int, Int]) - checkAll("MonadTrans[IdT]", SerializableTests.serializable(MonadTrans[IdT])) } { diff --git a/tests/src/test/scala/cats/tests/KleisliTests.scala b/tests/src/test/scala/cats/tests/KleisliTests.scala index 9e339928891..5dda6107708 100644 --- a/tests/src/test/scala/cats/tests/KleisliTests.scala +++ b/tests/src/test/scala/cats/tests/KleisliTests.scala @@ -24,8 +24,11 @@ class KleisliTests extends CatsSuite { implicit val iso = CartesianTests.Isomorphisms.invariant[Kleisli[Option, Int, ?]] implicit val iso2 = CartesianTests.Isomorphisms.invariant[Reader[Int, ?]] - checkAll("Kleisli[Option, Int, Int] with Unit", ApplicativeErrorTests[Kleisli[Option, Int, ?], Unit].applicativeError[Int, Int, Int]) - checkAll("ApplicativeError[Kleisli[Option, Int, Int], Unit]", SerializableTests.serializable(ApplicativeError[Kleisli[Option, Int, ?], Unit])) + { + implicit val instance: ApplicativeError[Kleisli[Option, Int, ?], Unit] = Kleisli.catsDataApplicativeErrorForKleisli[Option, Unit, Int](cats.instances.option.catsStdInstancesForOption) + checkAll("Kleisli[Option, Int, Int] with Unit", ApplicativeErrorTests[Kleisli[Option, Int, ?], Unit](instance).applicativeError[Int, Int, Int]) + checkAll("ApplicativeError[Kleisli[Option, Int, Int], Unit]", SerializableTests.serializable(instance)) + } checkAll("Kleisli[Option, Int, Int] with Unit", MonadErrorTests[Kleisli[Option, Int, ?], Unit].monadError[Int, Int, Int]) checkAll("MonadError[Kleisli[Option, Int, Int], Unit]", SerializableTests.serializable(MonadError[Kleisli[Option, Int, ?], Unit])) @@ -55,15 +58,15 @@ class KleisliTests extends CatsSuite { } { - implicit val catsDataMonadReaderForKleisli = Kleisli.catsDataMonadReaderForKleisli[Option, Int] - checkAll("Kleisli[Option, Int, Int]", MonadReaderTests[Kleisli[Option, Int, ?], Int].monadReader[Int, Int, Int]) - checkAll("MonadReader[Kleisli[Option, ?, ?], Int]", SerializableTests.serializable(MonadReader[Kleisli[Option, Int, ?], Int])) + implicit val catsDataMonadForKleisli = Kleisli.catsDataMonadForKleisli[Option, Int] + checkAll("Kleisli[Option, Int, Int]", MonadTests[Kleisli[Option, Int, ?]].monad[Int, Int, Int]) + checkAll("Monad[Kleisli[Option, ?, ?], Int]", SerializableTests.serializable(Monad[Kleisli[Option, Int, ?]])) } { - implicit val catsDataMonadReaderForReader = Kleisli.catsDataMonadReaderForKleisliId[Int] - checkAll("Reader[Int, Int]", MonadReaderTests[Reader[Int, ?], Int].monadReader[Int, Int, Int]) - checkAll("MonadReader[Reader[?, ?], Int]", SerializableTests.serializable(MonadReader[Reader[Int, ?], Int])) + implicit val catsDataMonadForReader = Kleisli.catsDataMonadForKleisliId[Int] + checkAll("Reader[Int, Int]", MonadTests[Reader[Int, ?]].monad[Int, Int, Int]) + checkAll("Monad[Reader[?, ?], Int]", SerializableTests.serializable(Monad[Reader[Int, ?]])) } { @@ -78,6 +81,12 @@ class KleisliTests extends CatsSuite { checkAll("FlatMap[Kleisli[Option, Int, ?]]", SerializableTests.serializable(FlatMap[Kleisli[Option, Int, ?]])) } + { + implicit val catsDataAlternativeForKleisli = Kleisli.catsDataAlternativeForKleisli[Option, Int] + checkAll("Kleisli[Option, Int, Int]", AlternativeTests[Kleisli[Option, Int, ?]].alternative[Int, Int, Int]) + checkAll("Alternative[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Alternative[Kleisli[Option, Int, ?]])) + } + { implicit val catsDataApplicativeForKleisli = Kleisli.catsDataApplicativeForKleisli[Option, Int] checkAll("Kleisli[Option, Int, Int]", ApplicativeTests[Kleisli[Option, Int, ?]].applicative[Int, Int, Int]) @@ -125,10 +134,6 @@ class KleisliTests extends CatsSuite { checkAll("Kleisli[Option, ?, Int]", ContravariantTests[Kleisli[Option, ?, Int]].contravariant[Int, Int, Int]) checkAll("Contravariant[Kleisli[Option, ?, Int]]", SerializableTests.serializable(Contravariant[Kleisli[Option, ?, Int]])) - checkAll("Kleisli[Option, Int, ?]]", MonadTransTests[Kleisli[?[_], Int, ?]].monadTrans[Option, Int, Int]) - checkAll("MonadTrans[Kleisli[?[_], Int, ?]]", SerializableTests.serializable(MonadTrans[Kleisli[?[_], Int, ?]])) - - test("local composes functions") { forAll { (f: Int => Option[String], g: Int => Int, i: Int) => f(g(i)) should === (Kleisli.local[Option, String, Int](g)(Kleisli(f)).run(i)) @@ -206,7 +211,6 @@ class KleisliTests extends CatsSuite { Apply[Kleisli[List, Int, ?]] Applicative[Kleisli[List, Int, ?]] Monad[Kleisli[List, Int, ?]] - MonadReader[Kleisli[List, Int, ?], Int] Monoid[Kleisli[List, Int, String]] MonoidK[λ[α => Kleisli[List, α, α]]] Arrow[Kleisli[List, ?, ?]] @@ -221,7 +225,6 @@ class KleisliTests extends CatsSuite { Apply[Kleisli[Id, Int, ?]] Applicative[Kleisli[Id, Int, ?]] Monad[Kleisli[Id, Int, ?]] - MonadReader[Kleisli[Id, Int, ?], Int] Monoid[Kleisli[Id, Int, String]] MonoidK[λ[α => Kleisli[Id, α, α]]] Arrow[Kleisli[Id, ?, ?]] @@ -237,7 +240,6 @@ class KleisliTests extends CatsSuite { Apply[Reader[Int, ?]] Applicative[Reader[Int, ?]] Monad[Reader[Int, ?]] - MonadReader[Reader[Int, ?], Int] Monoid[Reader[Int, String]] MonoidK[λ[α => Reader[α, α]]] Arrow[Reader[?, ?]] @@ -254,7 +256,6 @@ class KleisliTests extends CatsSuite { Apply[IntReader] Applicative[IntReader] Monad[IntReader] - MonadReader[IntReader, Int] Monoid[IntReader[String]] FlatMap[IntReader] Semigroup[IntReader[String]] @@ -262,7 +263,5 @@ class KleisliTests extends CatsSuite { ApplicativeError[Kleisli[cats.data.Validated[Unit, ?], Int, ?], Unit] ApplicativeError[Kleisli[Option, Int, ?], Unit] MonadError[Kleisli[Option, Int, ?], Unit] - - MonadTrans[Kleisli[?[_], Int, ?]] } } diff --git a/tests/src/test/scala/cats/tests/ListTests.scala b/tests/src/test/scala/cats/tests/ListTests.scala index 308e0672789..bb8640a296a 100644 --- a/tests/src/test/scala/cats/tests/ListTests.scala +++ b/tests/src/test/scala/cats/tests/ListTests.scala @@ -2,7 +2,7 @@ package cats package tests import cats.data.NonEmptyList -import cats.laws.discipline.{TraverseFilterTests, CoflatMapTests, MonadCombineTests, SerializableTests, CartesianTests} +import cats.laws.discipline.{TraverseTests, CoflatMapTests, AlternativeTests, SerializableTests, CartesianTests} import cats.laws.discipline.arbitrary._ class ListTests extends CatsSuite { @@ -13,11 +13,11 @@ class ListTests extends CatsSuite { checkAll("List[Int]", CoflatMapTests[List].coflatMap[Int, Int, Int]) checkAll("CoflatMap[List]", SerializableTests.serializable(CoflatMap[List])) - checkAll("List[Int]", MonadCombineTests[List].monadCombine[Int, Int, Int]) - checkAll("MonadCombine[List]", SerializableTests.serializable(MonadCombine[List])) + checkAll("List[Int]", AlternativeTests[List].alternative[Int, Int, Int]) + checkAll("Alternative[List]", SerializableTests.serializable(Alternative[List])) - checkAll("List[Int] with Option", TraverseFilterTests[List].traverseFilter[Int, Int, Int, List[Int], Option, Option]) - checkAll("TraverseFilter[List]", SerializableTests.serializable(TraverseFilter[List])) + checkAll("List[Int] with Option", TraverseTests[List].traverse[Int, Int, Int, List[Int], Option, Option]) + checkAll("Traverse[List]", SerializableTests.serializable(Traverse[List])) test("nel => list => nel returns original nel")( forAll { fa: NonEmptyList[Int] => diff --git a/tests/src/test/scala/cats/tests/ListWrapper.scala b/tests/src/test/scala/cats/tests/ListWrapper.scala index 91187fd6f81..7cc8e4ca9f7 100644 --- a/tests/src/test/scala/cats/tests/ListWrapper.scala +++ b/tests/src/test/scala/cats/tests/ListWrapper.scala @@ -44,28 +44,24 @@ object ListWrapper { def eqv[A : Eq]: Eq[ListWrapper[A]] = Eq[List[A]].on[ListWrapper[A]](_.list) - val traverseFilter: TraverseFilter[ListWrapper] = { - val F = TraverseFilter[List] + val traverse: Traverse[ListWrapper] = { + val F = Traverse[List] - new TraverseFilter[ListWrapper] { + new Traverse[ListWrapper] { def foldLeft[A, B](fa: ListWrapper[A], b: B)(f: (B, A) => B): B = F.foldLeft(fa.list, b)(f) def foldRight[A, B](fa: ListWrapper[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = F.foldRight(fa.list, lb)(f) - def traverseFilter[G[_], A, B](fa: ListWrapper[A])(f: A => G[Option[B]])(implicit G0: Applicative[G]): G[ListWrapper[B]] = { - G0.map(F.traverseFilter(fa.list)(f))(ListWrapper.apply) + def traverse[G[_], A, B](fa: ListWrapper[A])(f: A => G[B])(implicit G0: Applicative[G]): G[ListWrapper[B]] = { + G0.map(F.traverse(fa.list)(f))(ListWrapper.apply) } } } - val traverse: Traverse[ListWrapper] = traverseFilter - val foldable: Foldable[ListWrapper] = traverse val functor: Functor[ListWrapper] = traverse - val functorFilter: FunctorFilter[ListWrapper] = traverseFilter - val invariant: Invariant[ListWrapper] = functor val semigroupK: SemigroupK[ListWrapper] = @@ -76,41 +72,41 @@ object ListWrapper { def semigroup[A]: Semigroup[ListWrapper[A]] = semigroupK.algebra[A] - val monadCombine: MonadCombine[ListWrapper] = { - val M = MonadCombine[List] + val alternative: Alternative[ListWrapper] = { + val M = Alternative[List] - new MonadCombine[ListWrapper] { + new Alternative[ListWrapper] { def pure[A](x: A): ListWrapper[A] = ListWrapper(M.pure(x)) - def flatMap[A, B](fa: ListWrapper[A])(f: A => ListWrapper[B]): ListWrapper[B] = - ListWrapper(M.flatMap(fa.list)(a => f(a).list)) + def ap[A, B](f: ListWrapper[A => B])(fa: ListWrapper[A]): ListWrapper[B] = + ListWrapper(M.ap(f.list)(fa.list)) def empty[A]: ListWrapper[A] = ListWrapper(M.empty[A]) def combineK[A](x: ListWrapper[A], y: ListWrapper[A]): ListWrapper[A] = ListWrapper(M.combineK(x.list, y.list)) - - def tailRecM[A, B](a: A)(f: A => ListWrapper[Either[A,B]]): ListWrapper[B] = - ListWrapper(M.tailRecM(a)(a => f(a).list)) } } - val monad: Monad[ListWrapper] = monadCombine + val monad: Monad[ListWrapper] = new Monad[ListWrapper] { + val M = Monad[List] + def pure[A](x: A): ListWrapper[A] = ListWrapper(x :: Nil) - val flatMap: FlatMap[ListWrapper] = monadCombine + def flatMap[A, B](fa: ListWrapper[A])(f: (A) => ListWrapper[B]): ListWrapper[B] = ListWrapper(fa.list.flatMap(f(_).list)) - val applicative: Applicative[ListWrapper] = monadCombine + def tailRecM[A, B](a: A)(f: (A) => ListWrapper[Either[A, B]]): ListWrapper[B] = ListWrapper(M.tailRecM(a)(f(_).list)) + } - /** apply is taken due to ListWrapper being a case class */ - val applyInstance: Apply[ListWrapper] = monadCombine + val flatMap: FlatMap[ListWrapper] = monad - def monoidK: MonoidK[ListWrapper] = monadCombine + val applicative: Applicative[ListWrapper] = alternative - def monadFilter: MonadFilter[ListWrapper] = monadCombine + /** apply is taken due to ListWrapper being a case class */ + val applyInstance: Apply[ListWrapper] = alternative - def alternative: Alternative[ListWrapper] = monadCombine + def monoidK: MonoidK[ListWrapper] = alternative - def monoid[A]: Monoid[ListWrapper[A]] = monadCombine.algebra[A] + def monoid[A]: Monoid[ListWrapper[A]] = alternative.algebra[A] implicit def listWrapperArbitrary[A: Arbitrary]: Arbitrary[ListWrapper[A]] = Arbitrary(arbitrary[List[A]].map(ListWrapper.apply)) diff --git a/tests/src/test/scala/cats/tests/MapTests.scala b/tests/src/test/scala/cats/tests/MapTests.scala index e83d1d4c2d4..fb33354c64d 100644 --- a/tests/src/test/scala/cats/tests/MapTests.scala +++ b/tests/src/test/scala/cats/tests/MapTests.scala @@ -1,7 +1,7 @@ package cats package tests -import cats.laws.discipline.{TraverseFilterTests, FlatMapTests, SerializableTests, CartesianTests} +import cats.laws.discipline.{TraverseTests, FlatMapTests, SerializableTests, CartesianTests} class MapTests extends CatsSuite { implicit val iso = CartesianTests.Isomorphisms.invariant[Map[Int, ?]] @@ -12,8 +12,8 @@ class MapTests extends CatsSuite { checkAll("Map[Int, Int]", FlatMapTests[Map[Int, ?]].flatMap[Int, Int, Int]) checkAll("FlatMap[Map[Int, ?]]", SerializableTests.serializable(FlatMap[Map[Int, ?]])) - checkAll("Map[Int, Int] with Option", TraverseFilterTests[Map[Int, ?]].traverseFilter[Int, Int, Int, Int, Option, Option]) - checkAll("TraverseFilter[Map[Int, ?]]", SerializableTests.serializable(TraverseFilter[Map[Int, ?]])) + checkAll("Map[Int, Int] with Option", TraverseTests[Map[Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[Map[Int, ?]]", SerializableTests.serializable(Traverse[Map[Int, ?]])) test("show isn't empty and is formatted as expected") { forAll { (map: Map[Int, String]) => diff --git a/tests/src/test/scala/cats/tests/MonadCombineTests.scala b/tests/src/test/scala/cats/tests/MonadCombineTests.scala index c9f11e234ed..fbe83aea5fb 100644 --- a/tests/src/test/scala/cats/tests/MonadCombineTests.scala +++ b/tests/src/test/scala/cats/tests/MonadCombineTests.scala @@ -8,7 +8,7 @@ class MonadCombineTest extends CatsSuite { val strings = list.collect { case Right(s) => s } val expected = (ints, strings) - MonadCombine[List].separate(list) should === (expected) + Alternative[List].separate(list) should === (expected) } } } diff --git a/tests/src/test/scala/cats/tests/MonadStateTests.scala b/tests/src/test/scala/cats/tests/MonadStateTests.scala deleted file mode 100644 index 3c9d825b28a..00000000000 --- a/tests/src/test/scala/cats/tests/MonadStateTests.scala +++ /dev/null @@ -1,22 +0,0 @@ -package cats -package tests - -import cats.data.State - -class MonadStateTest extends CatsSuite { - val testInstance = MonadState[State[Int, ?], Int] - - test("MonadState#modify identity does not modify the state") { - forAll { (i: Int) => - val x = testInstance.modify(identity).runS(i).value - x should === (i) - } - } - - test("MonadState#inspect identity does not modify the state") { - forAll { (i: Int) => - val x = testInstance.inspect(identity).runA(i).value - x should === (i) - } - } -} diff --git a/tests/src/test/scala/cats/tests/MonadTest.scala b/tests/src/test/scala/cats/tests/MonadTest.scala index 8b8935a4973..063f389f9a8 100644 --- a/tests/src/test/scala/cats/tests/MonadTest.scala +++ b/tests/src/test/scala/cats/tests/MonadTest.scala @@ -5,22 +5,21 @@ import cats.data.{StateT} import org.scalacheck.Gen class MonadTest extends CatsSuite { - implicit val testInstance: MonadState[StateT[Id, Int, ?], Int] = StateT.catsDataMonadStateForStateT[Id, Int] - import testInstance._ + implicit val testInstance: Monad[StateT[Id, Int, ?]] = StateT.catsDataMonadForStateT[Id, Int] - val increment: StateT[Id, Int, Unit] = modify(_ + 1) - val incrementAndGet: StateT[Id, Int, Int] = increment >> get + val increment: StateT[Id, Int, Unit] = StateT.modify(_ + 1) + val incrementAndGet: StateT[Id, Int, Int] = increment >> StateT.get test("whileM_") { forAll(Gen.posNum[Int]) { (max: Int) => - val (result, _) = increment.whileM_(inspect(i => !(i >= max))).run(0) + val (result, _) = increment.whileM_(StateT.inspect(i => !(i >= max))).run(0) result should ===(Math.max(0, max)) } } test("whileM") { forAll(Gen.posNum[Int]) { (max: Int) => - val (result, aggregation) = incrementAndGet.whileM[Vector](inspect(i => !(i >= max))).run(0) + val (result, aggregation) = incrementAndGet.whileM[Vector](StateT.inspect(i => !(i >= max))).run(0) result should ===(Math.max(0, max)) aggregation should === ( if(max > 0) (1 to max).toVector else Vector.empty ) } @@ -28,26 +27,26 @@ class MonadTest extends CatsSuite { test("untilM_") { forAll(Gen.posNum[Int]) { (max: Int) => - val (result, _) = increment.untilM_(inspect(_ >= max)).run(-1) + val (result, _) = increment.untilM_(StateT.inspect(_ >= max)).run(-1) result should ===(max) } } test("untilM") { forAll(Gen.posNum[Int]) { (max: Int) => - val (result, aggregation) = incrementAndGet.untilM[Vector](inspect(_ >= max)).run(-1) + val (result, aggregation) = incrementAndGet.untilM[Vector](StateT.inspect(_ >= max)).run(-1) result should ===(max) aggregation should === ((0 to max).toVector) } } test("whileM_ stack safety") { - val (result, _) = increment.whileM_(inspect(i => !(i >= 50000))).run(0) + val (result, _) = increment.whileM_(StateT.inspect(i => !(i >= 50000))).run(0) result should ===(50000) } test("whileM stack safety") { - val (result, _) = incrementAndGet.whileM[Vector](inspect(i => !(i >= 50000))).run(0) + val (result, _) = incrementAndGet.whileM[Vector](StateT.inspect(i => !(i >= 50000))).run(0) result should ===(50000) } diff --git a/tests/src/test/scala/cats/tests/NestedTests.scala b/tests/src/test/scala/cats/tests/NestedTests.scala index 70000c172d2..44f53f63ead 100644 --- a/tests/src/test/scala/cats/tests/NestedTests.scala +++ b/tests/src/test/scala/cats/tests/NestedTests.scala @@ -44,25 +44,6 @@ class NestedTests extends CatsSuite { checkAll("Functor[Nested[Option, ListWrapper, ?]]", SerializableTests.serializable(Functor[Nested[Option, ListWrapper, ?]])) } - { - // FunctorFilter composition - implicit val instance = ListWrapper.functorFilter - checkAll("Nested[List, ListWrapper, ?]", FunctorFilterTests[Nested[List, ListWrapper, ?]].functorFilter[Int, Int, Int]) - checkAll("FunctorFilter[Nested[List, ListWrapper, ?]]", SerializableTests.serializable(FunctorFilter[Nested[List, ListWrapper, ?]])) - - test("collect consistency") { - forAll { l: Nested[List, ListWrapper, Int] => - l.collect(evenPf).value should === (l.value.map(_.collect(evenPf))) - } - } - - test("filter consistency") { - forAll { l: Nested[List, ListWrapper, Int] => - l.filter(even).value should === (l.value.map(_.filter(even))) - } - } - } - { // Covariant + contravariant functor composition checkAll("Nested[Option, Show, ?]", ContravariantTests[Nested[Option, Show, ?]].contravariant[Int, Int, Int]) @@ -118,14 +99,8 @@ class NestedTests extends CatsSuite { } { - // TraverseFilter composition - implicit val instance = ListWrapper.traverseFilter - checkAll("Nested[List, ListWrapper, ?]", TraverseFilterTests[Nested[List, ListWrapper, ?]].traverseFilter[Int, Int, Int, List[Int], Option, Option]) - checkAll("TraverseFilter[Nested[List, ListWrapper, ?]]", SerializableTests.serializable(TraverseFilter[Nested[List, ListWrapper, ?]])) - } - - { - implicit val foldable = ListWrapper.foldable + // Reducible composition + implicit val instance = ListWrapper.foldable checkAll("Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]", ReducibleTests[Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]].reducible[Option, Int, Int]) checkAll("Reducible[Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]]", SerializableTests.serializable(Reducible[Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]])) } @@ -134,10 +109,8 @@ class NestedTests extends CatsSuite { //NonEmptyTraverse composition checkAll("Nested[NonEmptyList, NonEmptyVector, ?]", NonEmptyTraverseTests[Nested[NonEmptyList, NonEmptyVector, ?]].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) checkAll("NonEmptyTraverse[Nested[NonEmptyList, NonEmptyVector, ?]]", SerializableTests.serializable(NonEmptyTraverse[Nested[NonEmptyList, NonEmptyVector, ?]])) - } - { // SemigroupK composition implicit val instance = ListWrapper.semigroupK diff --git a/tests/src/test/scala/cats/tests/OneAndTests.scala b/tests/src/test/scala/cats/tests/OneAndTests.scala index 8033592ccbf..8f02a6012ed 100644 --- a/tests/src/test/scala/cats/tests/OneAndTests.scala +++ b/tests/src/test/scala/cats/tests/OneAndTests.scala @@ -19,7 +19,7 @@ class OneAndTests extends CatsSuite { checkAll("NonEmptyTraverse[OneAnd[Stream, A]]", SerializableTests.serializable(NonEmptyTraverse[OneAnd[Stream, ?]])) { - implicit val traverse = ListWrapper.traverse + implicit val traverse = OneAnd.catsDataTraverseForOneAnd(ListWrapper.traverse) checkAll("OneAnd[ListWrapper, Int] with Option", TraverseTests[OneAnd[ListWrapper, ?]].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[OneAnd[ListWrapper, A]]", SerializableTests.serializable(Traverse[OneAnd[ListWrapper, ?]])) } @@ -31,9 +31,10 @@ class OneAndTests extends CatsSuite { // Test instances that have more general constraints { - implicit val monadCombine = ListWrapper.monadCombine - checkAll("OneAnd[ListWrapper, Int]", CartesianTests[OneAnd[ListWrapper, ?]].cartesian[Int, Int, Int]) - checkAll("Cartesian[OneAnd[ListWrapper, A]]", SerializableTests.serializable(Cartesian[OneAnd[ListWrapper, ?]])) + implicit val monad = ListWrapper.monad + implicit val alt = ListWrapper.alternative + checkAll("OneAnd[ListWrapper, Int]", MonadTests[OneAnd[ListWrapper, ?]].monad[Int, Int, Int]) + checkAll("MonadTests[OneAnd[ListWrapper, A]]", SerializableTests.serializable(Monad[OneAnd[ListWrapper, ?]])) } { @@ -43,7 +44,7 @@ class OneAndTests extends CatsSuite { } { - implicit val monadCombine = ListWrapper.monadCombine + implicit val alternative = ListWrapper.alternative checkAll("OneAnd[ListWrapper, Int]", SemigroupKTests[OneAnd[ListWrapper, ?]].semigroupK[Int]) checkAll("OneAnd[Stream, Int]", GroupLaws[OneAnd[Stream, Int]].semigroup) checkAll("SemigroupK[OneAnd[ListWrapper, A]]", SerializableTests.serializable(SemigroupK[OneAnd[ListWrapper, ?]])) @@ -99,13 +100,6 @@ class OneAndTests extends CatsSuite { } } - test("NonEmptyStream#filter is consistent with Stream#filter") { - forAll { (nel: NonEmptyStream[Int], p: Int => Boolean) => - val stream = nel.unwrap - nel.filter(p) should === (stream.filter(p)) - } - } - test("NonEmptyStream#find is consistent with Stream#find") { forAll { (nel: NonEmptyStream[Int], p: Int => Boolean) => val stream = nel.unwrap @@ -180,6 +174,13 @@ class OneAndTests extends CatsSuite { got should === (expected) } } + + test("filter includes elements based on a predicate") { + forAll { (nes: NonEmptyStream[Int], pred: Int => Boolean) => + nes.filter(pred) should ===(nes.unwrap.filter(pred)) + } + } + } class ReducibleNonEmptyStreamCheck extends ReducibleCheck[NonEmptyStream]("NonEmptyStream") { diff --git a/tests/src/test/scala/cats/tests/OptionTTests.scala b/tests/src/test/scala/cats/tests/OptionTTests.scala index b381d12dcbc..450b4e915ec 100644 --- a/tests/src/test/scala/cats/tests/OptionTTests.scala +++ b/tests/src/test/scala/cats/tests/OptionTTests.scala @@ -7,7 +7,7 @@ import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ class OptionTTests extends CatsSuite { - implicit val iso = CartesianTests.Isomorphisms.invariant[OptionT[ListWrapper, ?]](OptionT.catsDataFunctorFilterForOptionT(ListWrapper.functor)) + implicit val iso = CartesianTests.Isomorphisms.invariant[OptionT[ListWrapper, ?]](OptionT.catsDataFunctorForOptionT(ListWrapper.functor)) { implicit val F = ListWrapper.eqv[Option[Int]] @@ -39,8 +39,8 @@ class OptionTTests extends CatsSuite { // F has a Functor implicit val F = ListWrapper.functor - checkAll("OptionT[ListWrapper, Int]", FunctorFilterTests[OptionT[ListWrapper, ?]].functorFilter[Int, Int, Int]) - checkAll("FunctorFilter[OptionT[ListWrapper, ?]]", SerializableTests.serializable(FunctorFilter[OptionT[ListWrapper, ?]])) + checkAll("OptionT[ListWrapper, Int]", FunctorTests[OptionT[ListWrapper, ?]].functor[Int, Int, Int]) + checkAll("Functor[OptionT[ListWrapper, ?]]", SerializableTests.serializable(Functor[OptionT[ListWrapper, ?]])) } { @@ -58,9 +58,7 @@ class OptionTTests extends CatsSuite { checkAll("OptionT[ListWrapper, Int]", MonoidKTests[OptionT[ListWrapper, ?]].monoidK[Int]) checkAll("MonoidK[OptionT[ListWrapper, ?]]", SerializableTests.serializable(MonoidK[OptionT[ListWrapper, ?]])) - checkAll("OptionT[ListWrapper, Int]]", MonadTransTests[OptionT].monadTrans[ListWrapper, Int, Int]) - checkAll("MonadTrans[OptionT]", SerializableTests.serializable(MonadTrans[OptionT])) - + Monad[OptionT[ListWrapper, ?]] FlatMap[OptionT[ListWrapper, ?]] Applicative[OptionT[ListWrapper, ?]] Apply[OptionT[ListWrapper, ?]] @@ -98,8 +96,8 @@ class OptionTTests extends CatsSuite { // F has a Traverse implicit val F = ListWrapper.traverse - checkAll("OptionT[ListWrapper, Int] with Option", TraverseFilterTests[OptionT[ListWrapper, ?]].traverseFilter[Int, Int, Int, Int, Option, Option]) - checkAll("TraverseFilter[OptionT[ListWrapper, ?]]", SerializableTests.serializable(TraverseFilter[OptionT[ListWrapper, ?]])) + checkAll("OptionT[ListWrapper, Int] with Option", TraverseTests[OptionT[ListWrapper, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[OptionT[ListWrapper, ?]]", SerializableTests.serializable(Traverse[OptionT[ListWrapper, ?]])) Foldable[OptionT[ListWrapper, ?]] Functor[OptionT[ListWrapper, ?]] @@ -281,6 +279,11 @@ class OptionTTests extends CatsSuite { } } + test("mapFilter consistent with subflatMap") { + forAll { (o: OptionT[List, Int], f: Int => Option[String]) => + o.mapFilter(f) should === (o.subflatMap(f)) + } + } /** * Testing that implicit resolution works. If it compiles, the "test" passes. @@ -310,8 +313,6 @@ class OptionTTests extends CatsSuite { implicit val T = ListWrapper.traverse implicit val M = ListWrapper.monad Functor[OptionT[ListWrapper, ?]] - - MonadTrans[OptionT] } } diff --git a/tests/src/test/scala/cats/tests/OptionTests.scala b/tests/src/test/scala/cats/tests/OptionTests.scala index bd86eba79fb..b8b15285b8e 100644 --- a/tests/src/test/scala/cats/tests/OptionTests.scala +++ b/tests/src/test/scala/cats/tests/OptionTests.scala @@ -11,14 +11,14 @@ class OptionTests extends CatsSuite { checkAll("Option[Int]", CoflatMapTests[Option].coflatMap[Int, Int, Int]) checkAll("CoflatMap[Option]", SerializableTests.serializable(CoflatMap[Option])) - checkAll("Option[Int]", MonadCombineTests[Option].monadCombine[Int, Int, Int]) - checkAll("MonadCombine[Option]", SerializableTests.serializable(MonadCombine[Option])) + checkAll("Option[Int]", AlternativeTests[Option].alternative[Int, Int, Int]) + checkAll("Alternative[Option]", SerializableTests.serializable(Alternative[Option])) checkAll("Option[Int]", CommutativeMonadTests[Option].commutativeMonad[Int, Int, Int]) checkAll("CommutativeMonad[Option]", SerializableTests.serializable(CommutativeMonad[Option])) - checkAll("Option[Int] with Option", TraverseFilterTests[Option].traverseFilter[Int, Int, Int, Int, Option, Option]) - checkAll("TraverseFilter[Option]", SerializableTests.serializable(TraverseFilter[Option])) + checkAll("Option[Int] with Option", TraverseTests[Option].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[Option]", SerializableTests.serializable(Traverse[Option])) checkAll("Option with Unit", MonadErrorTests[Option, Unit].monadError[Int, Int, Int]) checkAll("MonadError[Option, Unit]", SerializableTests.serializable(MonadError[Option, Unit])) diff --git a/tests/src/test/scala/cats/tests/ReaderWriterStateTTests.scala b/tests/src/test/scala/cats/tests/ReaderWriterStateTTests.scala index 821ddeb8351..de379464a18 100644 --- a/tests/src/test/scala/cats/tests/ReaderWriterStateTTests.scala +++ b/tests/src/test/scala/cats/tests/ReaderWriterStateTTests.scala @@ -2,7 +2,7 @@ package cats package tests import cats.data.{ ReaderWriterStateT, ReaderWriterState, EitherT } -import cats.functor.{Contravariant, Profunctor } +import cats.functor.{ Contravariant, Profunctor } import cats.laws.discipline._ import cats.laws.discipline.eq._ import cats.laws.discipline.arbitrary._ @@ -311,44 +311,6 @@ class ReaderWriterStateTTests extends CatsSuite { SerializableTests.serializable(Monad[ReaderWriterStateT[ListWrapper, String, String, Int, ?]])) } - { - implicit val LWM: Monad[ListWrapper] = ListWrapper.monad - - checkAll("ReaderWriterStateT[ListWrapper, String, String, Int, Int]", - MonadStateTests[ReaderWriterStateT[ListWrapper, String, String, Int, ?], Int].monadState[Int, Int, Int]) - checkAll("MonadState[ReaderWriterStateT[ListWrapper, String, String, Int, ?]. Int]", - SerializableTests.serializable(MonadState[ReaderWriterStateT[ListWrapper, String, String, Int, ?], Int])) - } - - { - implicit val LWM: MonadCombine[ListWrapper] = ListWrapper.monadCombine - - checkAll("ReaderWriterStateT[ListWrapper, String, String, Int, Int]", - MonadCombineTests[ReaderWriterStateT[ListWrapper, String, String, Int, ?]].monadCombine[Int, Int, Int]) - checkAll("MonadCombine[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]", - SerializableTests.serializable(MonadCombine[ReaderWriterStateT[ListWrapper, String, String, Int, ?]])) - } - - { - implicit val LWM: Monad[ListWrapper] = ListWrapper.monad - - checkAll("ReaderWriterStateT[ListWrapper, String, String, Int, Int]", - MonadReaderTests[ReaderWriterStateT[ListWrapper, String, String, Int, ?], String].monadReader[String, String, String]) - - // check serializable using Option - checkAll("MonadReader[ReaderWriterStateT[Option, String, String, Int, ?], String]", - SerializableTests.serializable(MonadReader[ReaderWriterStateT[Option, String, String, Int, ?], String])) - } - - { - implicit val LWM: Monad[ListWrapper] = ListWrapper.monad - - checkAll("ReaderWriterStateT[ListWrapper, String, String, Int, Int]", - MonadWriterTests[ReaderWriterStateT[ListWrapper, String, String, Int, ?], String].monadWriter[String, String, String]) - checkAll("MonadWriter[ReaderWriterStateT[ListWrapper, String, String, Int, ?], String]", - SerializableTests.serializable(MonadWriter[ReaderWriterStateT[ListWrapper, String, String, Int, ?], String])) - } - { implicit val iso = CartesianTests.Isomorphisms.invariant[ReaderWriterStateT[Option, String, String, Int, ?]] implicit val eqEitherTFA: Eq[EitherT[ReaderWriterStateT[Option, String, String, Int, ?], Unit, Int]] = @@ -370,15 +332,6 @@ class ReaderWriterStateTTests extends CatsSuite { SerializableTests.serializable(SemigroupK[ReaderWriterStateT[ListWrapper, String, String, Int, ?]])) } - { - implicit val F: Monad[ListWrapper] = ListWrapper.monad - - checkAll("ReaderWriterStateT[ListWrapper, String, String, Int, Int]]", - MonadTransTests[ReaderWriterStateT[?[_], String, String, Int, ?]].monadTrans[ListWrapper, Int, Int]) - checkAll("MonadTrans[ReaderWriterStateT[?[_], String, String, Int, ?]]", - SerializableTests.serializable(MonadTrans[ReaderWriterStateT[?[_], String, String, Int, ?]])) - } - } object ReaderWriterStateTTests { diff --git a/tests/src/test/scala/cats/tests/StateTTests.scala b/tests/src/test/scala/cats/tests/StateTTests.scala index c86ae6dd6ba..81c1ee99ede 100644 --- a/tests/src/test/scala/cats/tests/StateTTests.scala +++ b/tests/src/test/scala/cats/tests/StateTTests.scala @@ -219,36 +219,18 @@ class StateTTests extends CatsSuite { Functor[StateT[ListWrapper, Int, ?]] } - { - // F has a Monad - implicit val F = ListWrapper.monad - - checkAll("StateT[ListWrapper, Int, Int]", MonadStateTests[StateT[ListWrapper, Int, ?], Int].monadState[Int, Int, Int]) - checkAll("MonadState[StateT[ListWrapper, Int, ?], Int]", SerializableTests.serializable(MonadState[StateT[ListWrapper, Int, ?], Int])) - - Monad[StateT[ListWrapper, Int, ?]] - FlatMap[StateT[ListWrapper, Int, ?]] - Applicative[StateT[ListWrapper, Int, ?]] - Apply[StateT[ListWrapper, Int, ?]] - Functor[StateT[ListWrapper, Int, ?]] - } - { // F has a Monad implicit val F = ListWrapper.monad checkAll("StateT[ListWrapper, Int, Int]", MonadTests[StateT[ListWrapper, Int, ?]].monad[Int, Int, Int]) checkAll("Monad[StateT[ListWrapper, Int, ?]]", SerializableTests.serializable(Monad[StateT[ListWrapper, Int, ?]])) - checkAll("StateT[ListWrapper, Int, Int]", MonadTransTests[StateT[?[_], String, ?]].monadTrans[ListWrapper, Int, Int]) - checkAll("MonadTrans[StateT[?[_], Int, ?]]", SerializableTests.serializable(MonadTrans[StateT[?[_], Int, ?]])) Monad[StateT[ListWrapper, Int, ?]] FlatMap[StateT[ListWrapper, Int, ?]] Applicative[StateT[ListWrapper, Int, ?]] Apply[StateT[ListWrapper, Int, ?]] Functor[StateT[ListWrapper, Int, ?]] - - MonadTrans[StateT[?[_], Int, ?]] } { @@ -261,11 +243,12 @@ class StateTTests extends CatsSuite { } { - // F has a MonadCombine - implicit val F = ListWrapper.monadCombine - - checkAll("StateT[ListWrapper, Int, Int]", MonadCombineTests[StateT[ListWrapper, Int, ?]].monadCombine[Int, Int, Int]) - checkAll("MonadCombine[StateT[ListWrapper, Int, ?]]", SerializableTests.serializable(MonadCombine[StateT[ListWrapper, Int, ?]])) + // F has an Alternative + implicit val G = ListWrapper.monad + implicit val F = ListWrapper.alternative + val SA = StateT.catsDataAlternativeForStateT[ListWrapper, Int](ListWrapper.monad, ListWrapper.alternative) + checkAll("StateT[ListWrapper, Int, Int]", AlternativeTests[StateT[ListWrapper, Int, ?]](SA).monoidK[Int]) + checkAll("Alternative[StateT[ListWrapper, Int, ?]]", SerializableTests.serializable(SA)) Monad[StateT[ListWrapper, Int, ?]] FlatMap[StateT[ListWrapper, Int, ?]] @@ -280,9 +263,6 @@ class StateTTests extends CatsSuite { { implicit val iso = CartesianTests.Isomorphisms.invariant[State[Long, ?]] - checkAll("State[Long, ?]", MonadStateTests[State[Long, ?], Long].monadState[Int, Int, Int]) - checkAll("MonadState[State[Long, ?], Long]", SerializableTests.serializable(MonadState[State[Long, ?], Long])) - checkAll("State[Long, ?]", MonadTests[State[Long, ?]].monad[Int, Int, Int]) checkAll("Monad[State[Long, ?]]", SerializableTests.serializable(Monad[State[Long, ?]])) } @@ -292,8 +272,8 @@ class StateTTests extends CatsSuite { implicit val iso = CartesianTests.Isomorphisms.invariant[StateT[Option, Int, ?]] implicit val eqEitherTFA: Eq[EitherT[StateT[Option, Int , ?], Unit, Int]] = EitherT.catsDataEqForEitherT[StateT[Option, Int , ?], Unit, Int] - checkAll("StateT[Option, Int, Int]", MonadErrorTests[StateT[Option, Int , ?], Unit].monadError[Int, Int, Int]) - checkAll("MonadError[StateT[Option, Int , ?], Unit]", SerializableTests.serializable(MonadError[StateT[Option, Int , ?], Unit])) + checkAll("StateT[Option, Int, Int]", MonadErrorTests[StateT[Option, Int, ?], Unit].monadError[Int, Int, Int]) + checkAll("MonadError[StateT[Option, Int, ?], Unit]", SerializableTests.serializable(MonadError[StateT[Option, Int , ?], Unit])) } } diff --git a/tests/src/test/scala/cats/tests/StreamTests.scala b/tests/src/test/scala/cats/tests/StreamTests.scala index 0fec800c772..8ea90f21e96 100644 --- a/tests/src/test/scala/cats/tests/StreamTests.scala +++ b/tests/src/test/scala/cats/tests/StreamTests.scala @@ -1,7 +1,7 @@ package cats package tests -import cats.laws.discipline.{CoflatMapTests, MonadCombineTests, SerializableTests, TraverseFilterTests, CartesianTests} +import cats.laws.discipline.{CoflatMapTests, MonadTests, AlternativeTests, SerializableTests, TraverseTests, CartesianTests} class StreamTests extends CatsSuite { checkAll("Stream[Int]", CartesianTests[Stream].cartesian[Int, Int, Int]) @@ -10,11 +10,14 @@ class StreamTests extends CatsSuite { checkAll("Stream[Int]", CoflatMapTests[Stream].coflatMap[Int, Int, Int]) checkAll("CoflatMap[Stream]", SerializableTests.serializable(CoflatMap[Stream])) - checkAll("Stream[Int]", MonadCombineTests[Stream].monadCombine[Int, Int, Int]) - checkAll("MonadCombine[Stream]", SerializableTests.serializable(MonadCombine[Stream])) + checkAll("Stream[Int]", AlternativeTests[Stream].alternative[Int, Int, Int]) + checkAll("Alternative[Stream]", SerializableTests.serializable(Alternative[Stream])) - checkAll("Stream[Int] with Option", TraverseFilterTests[Stream].traverseFilter[Int, Int, Int, List[Int], Option, Option]) - checkAll("TraverseFilter[Stream]", SerializableTests.serializable(TraverseFilter[Stream])) + checkAll("Stream[Int]", MonadTests[Stream].monad[Int, Int, Int]) + checkAll("Monad[Stream]", SerializableTests.serializable(Monad[Stream])) + + checkAll("Stream[Int] with Option", TraverseTests[Stream].traverse[Int, Int, Int, List[Int], Option, Option]) + checkAll("Traverse[Stream]", SerializableTests.serializable(Traverse[Stream])) test("show") { Stream(1, 2, 3).show should === ("Stream(1, ?)") @@ -38,9 +41,4 @@ class StreamTests extends CatsSuite { } } - test("collect consistency") { - forAll { s: Stream[Int] => - FunctorFilter[Stream].collect(s)(evenPf) should === (s.collect(evenPf)) - } - } } diff --git a/tests/src/test/scala/cats/tests/SyntaxTests.scala b/tests/src/test/scala/cats/tests/SyntaxTests.scala index f99472a8dcd..c4e17a28e43 100644 --- a/tests/src/test/scala/cats/tests/SyntaxTests.scala +++ b/tests/src/test/scala/cats/tests/SyntaxTests.scala @@ -253,7 +253,7 @@ object SyntaxTests extends AllInstances with AllSyntax { val gfab = fgagb.bisequence } - def testMonadCombine[F[_]: MonadCombine, G[_]: Foldable, H[_, _]: Bifoldable, A, B]: Unit = { + def testAlternativeMonad[F[_]: Alternative: Monad, G[_]: Foldable, H[_, _]: Bifoldable, A, B]: Unit = { val fga = mock[F[G[A]]] val fa = fga.unite @@ -266,11 +266,6 @@ object SyntaxTests extends AllInstances with AllSyntax { val fa = a.pure[F] } - def testMonadTrans[MT[_[_], _], M[_], A](implicit MT: MonadTrans[MT], M: Monad[M]): Unit = { - val fa = mock[M[A]] - val mtf = fa.liftT[MT] - } - def testFlatMap[F[_] : FlatMap, A, B]: Unit = { val a = mock[A] val returnValue = mock[F[Either[A, B]]] @@ -304,25 +299,3 @@ object SyntaxTests extends AllInstances with AllSyntax { } -/** - * Similar to [[SyntaxTests]] but doesn't automatically include all - * instances/syntax, so that piecemeal imports can be tested. - */ -object AdHocSyntaxTests { - import SyntaxTests.mock - - def testFunctorFilterSyntax[F[_]:FunctorFilter, A]: Unit = { - import cats.syntax.functorFilter._ - - val fa = mock[F[A]] - val filtered = fa.mapFilter(_ => None) - } - - def testTraverseFilterSyntax[F[_]:TraverseFilter, G[_]: Applicative, A, B]: Unit = { - import cats.syntax.traverseFilter._ - - val fa = mock[F[A]] - val f = mock[A => G[Option[B]]] - val filtered = fa.traverseFilter(f) - } -} diff --git a/tests/src/test/scala/cats/tests/Tuple2KTests.scala b/tests/src/test/scala/cats/tests/Tuple2KTests.scala index ba0605c9d93..fa041999fae 100644 --- a/tests/src/test/scala/cats/tests/Tuple2KTests.scala +++ b/tests/src/test/scala/cats/tests/Tuple2KTests.scala @@ -72,13 +72,6 @@ class Tuple2KTests extends CatsSuite { checkAll("Alternative[Tuple2K[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(Alternative[Tuple2K[ListWrapper, ListWrapper, ?]])) } - { - implicit val monadCombine = ListWrapper.monadCombine - implicit val iso = CartesianTests.Isomorphisms.invariant[Tuple2K[ListWrapper, ListWrapper, ?]] - checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", MonadCombineTests[Tuple2K[ListWrapper, ListWrapper, ?]].monadCombine[Int, Int, Int]) - checkAll("MonadCombine[Tuple2K[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(MonadCombine[Tuple2K[ListWrapper, ListWrapper, ?]])) - } - { implicit val E = ListWrapper.eqv[Int] implicit val O = ListWrapper.order[Int] diff --git a/tests/src/test/scala/cats/tests/ValidatedTests.scala b/tests/src/test/scala/cats/tests/ValidatedTests.scala index 98856ca6faf..dc152a5340d 100644 --- a/tests/src/test/scala/cats/tests/ValidatedTests.scala +++ b/tests/src/test/scala/cats/tests/ValidatedTests.scala @@ -3,7 +3,7 @@ package tests import cats.data._ import cats.data.Validated.{Invalid, Valid} -import cats.laws.discipline.{ApplicativeErrorTests, BitraverseTests, CartesianTests, SerializableTests, TraverseTests} +import cats.laws.discipline._ import org.scalacheck.Arbitrary._ import cats.laws.discipline.SemigroupKTests import cats.laws.discipline.arbitrary._ diff --git a/tests/src/test/scala/cats/tests/VectorTests.scala b/tests/src/test/scala/cats/tests/VectorTests.scala index bc67542b275..d1251f94148 100644 --- a/tests/src/test/scala/cats/tests/VectorTests.scala +++ b/tests/src/test/scala/cats/tests/VectorTests.scala @@ -2,7 +2,7 @@ package cats package tests import cats.data.NonEmptyVector -import cats.laws.discipline.{MonadCombineTests, CoflatMapTests, SerializableTests, TraverseFilterTests, CartesianTests} +import cats.laws.discipline.{AlternativeTests, CoflatMapTests, SerializableTests, TraverseTests, CartesianTests} import cats.laws.discipline.arbitrary._ class VectorTests extends CatsSuite { @@ -12,11 +12,11 @@ class VectorTests extends CatsSuite { checkAll("Vector[Int]", CoflatMapTests[Vector].coflatMap[Int, Int, Int]) checkAll("CoflatMap[Vector]", SerializableTests.serializable(CoflatMap[Vector])) - checkAll("Vector[Int]", MonadCombineTests[Vector].monadCombine[Int, Int, Int]) - checkAll("MonadCombine[Vector]", SerializableTests.serializable(MonadCombine[Vector])) + checkAll("Vector[Int]", AlternativeTests[Vector].alternative[Int, Int, Int]) + checkAll("Alternative[Vector]", SerializableTests.serializable(Alternative[Vector])) - checkAll("Vector[Int] with Option", TraverseFilterTests[Vector].traverseFilter[Int, Int, Int, List[Int], Option, Option]) - checkAll("TraverseFilter[Vector]", SerializableTests.serializable(TraverseFilter[Vector])) + checkAll("Vector[Int] with Option", TraverseTests[Vector].traverse[Int, Int, Int, List[Int], Option, Option]) + checkAll("Traverse[Vector]", SerializableTests.serializable(Traverse[Vector])) test("show") { Vector(1, 2, 3).show should === ("Vector(1, 2, 3)") @@ -28,12 +28,6 @@ class VectorTests extends CatsSuite { } } - test("collect consistency") { - forAll { vec: Vector[Int] => - FunctorFilter[Vector].collect(vec)(evenPf) should === (vec.collect(evenPf)) - } - } - test("nev => vector => nev returns original nev")( forAll { fa: NonEmptyVector[Int] => assert(fa.toVector.toNev == Some(fa)) diff --git a/tests/src/test/scala/cats/tests/WriterTTests.scala b/tests/src/test/scala/cats/tests/WriterTTests.scala index 2ec46d9050c..2f3daa19c0e 100644 --- a/tests/src/test/scala/cats/tests/WriterTTests.scala +++ b/tests/src/test/scala/cats/tests/WriterTTests.scala @@ -85,14 +85,6 @@ class WriterTTests extends CatsSuite { w2.tell("bar") should === (Writer("foobar", 3)) } - test("MonadWriter's tell is consistent with WriterT's tell") { - type Logged[A] = Writer[String, A] - val w = MonadWriter[Logged, String] - val x = w.tell("foo") - x should === (Writer.tell("foo")) - x should === (Writer("foo", ())) - } - test("tell instantiates a Writer") { Writer.tell("foo").written should === ("foo") } @@ -254,11 +246,8 @@ class WriterTTests extends CatsSuite { Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]] FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] CoflatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", MonadWriterTests[WriterT[ListWrapper, ListWrapper[Int], ?], ListWrapper[Int]].monadWriter[Int, Int, Int]) - checkAll("MonadWriter[WriterT[ListWrapper, ListWrapper[Int], ?], List[String]]", SerializableTests.serializable(MonadWriter[WriterT[ListWrapper, ListWrapper[Int], ?], ListWrapper[Int]])) - - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]]", MonadTransTests[WriterT[?[_], ListWrapper[Int], ?]].monadTrans[ListWrapper, Int, Int]) - checkAll("MonadTrans[WriterT[?[_], ListWrapper[Int], ?]]", SerializableTests.serializable(MonadTrans[WriterT[?[_], ListWrapper[Int], ?]])) + checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", MonadTests[WriterT[ListWrapper, ListWrapper[Int], ?]].monad[Int, Int, Int]) + checkAll("Monad[WriterT[ListWrapper, ListWrapper[Int], ?], List[String]]", SerializableTests.serializable(Monad[WriterT[ListWrapper, ListWrapper[Int], ?]])) Functor[WriterT[Id, ListWrapper[Int], ?]] Apply[WriterT[Id, ListWrapper[Int], ?]] @@ -266,7 +255,6 @@ class WriterTTests extends CatsSuite { FlatMap[WriterT[Id, ListWrapper[Int], ?]] CoflatMap[WriterT[Id, ListWrapper[Int], ?]] Monad[WriterT[Id, ListWrapper[Int], ?]] - MonadTrans[WriterT[?[_], ListWrapper[Int], ?]] Functor[Writer[ListWrapper[Int], ?]] Apply[Writer[ListWrapper[Int], ?]] @@ -291,45 +279,12 @@ class WriterTTests extends CatsSuite { Functor[WriterT[ListWrapper, ListWrapper[Int], ?]] Apply[WriterT[ListWrapper, ListWrapper[Int], ?]] Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]] + Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]] CoflatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", AlternativeTests[WriterT[ListWrapper, ListWrapper[Int], ?]].alternative[Int, Int, Int]) checkAll("Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]])) } - { - // F has a MonadFilter and L has a Monoid - implicit val F: MonadFilter[ListWrapper] = ListWrapper.monadFilter - implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int] - - Functor[WriterT[ListWrapper, ListWrapper[Int], ?]] - Apply[WriterT[ListWrapper, ListWrapper[Int], ?]] - Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]] - FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] - CoflatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] - Monad[WriterT[ListWrapper, ListWrapper[Int], ?]] - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", MonadFilterTests[WriterT[ListWrapper, ListWrapper[Int], ?]].monadFilter[Int, Int, Int]) - checkAll("MonadFilter[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(MonadFilter[WriterT[ListWrapper, ListWrapper[Int], ?]])) - } - - { - // F has a MonadCombine and L has a Monoid - implicit val F: MonadCombine[ListWrapper] = ListWrapper.monadCombine - implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int] - - Functor[WriterT[ListWrapper, ListWrapper[Int], ?]] - Apply[WriterT[ListWrapper, ListWrapper[Int], ?]] - Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]] - FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] - CoflatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] - Monad[WriterT[ListWrapper, ListWrapper[Int], ?]] - MonadFilter[WriterT[ListWrapper, ListWrapper[Int], ?]] - Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]] - SemigroupK[WriterT[ListWrapper, ListWrapper[Int], ?]] - MonoidK[WriterT[ListWrapper, ListWrapper[Int], ?]] - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", MonadCombineTests[WriterT[ListWrapper, ListWrapper[Int], ?]].monadCombine[Int, Int, Int]) - checkAll("MonadCombine[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(MonadCombine[WriterT[ListWrapper, ListWrapper[Int], ?]])) - } - { // F[(L, V)] has a monoid implicit val FLV: Monoid[ListWrapper[(Int, Int)]] = ListWrapper.monoid[(Int, Int)] @@ -355,9 +310,9 @@ class WriterTTests extends CatsSuite { } { - // F has an ApplicativeError and L has a Monoid + // F has an Applicative and L has a Monoid implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int] - implicit val appErr = WriterT.catsDataApplicativeErrorForWriterT[Validated[String, ?], ListWrapper[Int], String] + implicit val appErr = WriterT.catsDataApplicativeForWriterT[Validated[String, ?], ListWrapper[Int]] implicit val iso = CartesianTests.Isomorphisms.invariant[WriterT[Validated[String, ?], ListWrapper[Int], ?]] implicit def eq1[A:Eq]: Eq[WriterT[Validated[String, ?], ListWrapper[Int], A]] = WriterT.catsDataEqForWriterT[Validated[String, ?], ListWrapper[Int], A] @@ -368,6 +323,15 @@ class WriterTTests extends CatsSuite { Apply[WriterT[Validated[String, ?], ListWrapper[Int], ?]] Applicative[WriterT[Validated[String, ?], ListWrapper[Int], ?]] + checkAll("WriterT[Validated[String, ?], ListWrapper[Int], ?]", ApplicativeTests[WriterT[Validated[String, ?], ListWrapper[Int], ?]].applicative[Int, Int, Int]) + checkAll("Applicative[WriterT[Validated[String, ?], ListWrapper[Int], ?]]", SerializableTests.serializable(Applicative[WriterT[Validated[String, ?], ListWrapper[Int], ?]])) + } + + { + // F has an ApplicativeError and L has a Monoid + implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int] + implicit val appErr = WriterT.catsDataApplicativeErrorForWriterT[Validated[String, ?], ListWrapper[Int], String] + implicit val iso = CartesianTests.Isomorphisms.invariant[WriterT[Validated[String, ?], ListWrapper[Int], ?]] checkAll("WriterT[Validated[String, ?], ListWrapper[Int], ?]", ApplicativeErrorTests[WriterT[Validated[String, ?], ListWrapper[Int], ?], String].applicativeError[Int, Int, Int]) checkAll("ApplicativeError[WriterT[Validated[String, ?], ListWrapper[Int], ?], Unit]", SerializableTests.serializable(ApplicativeError[WriterT[Validated[String, ?], ListWrapper[Int], ?], String])) } @@ -385,7 +349,6 @@ class WriterTTests extends CatsSuite { FlatMap[WriterT[Option, ListWrapper[Int], ?]] CoflatMap[WriterT[Option, ListWrapper[Int], ?]] Monad[WriterT[Option, ListWrapper[Int], ?]] - MonadWriter[WriterT[Option, ListWrapper[Int], ?], ListWrapper[Int]] ApplicativeError[WriterT[Option, ListWrapper[Int], ?], Unit] checkAll("WriterT[Option, ListWrapper[Int], ?]", MonadErrorTests[WriterT[Option, ListWrapper[Int], ?], Unit].monadError[Int, Int, Int])