From b071721816333763954cee01a9c87f1a4d97839e Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Fri, 30 May 2025 20:57:57 +0200 Subject: [PATCH] Reduce jar size by using abstract classes Traits generate bridge methods in every subclass --- .../main/scala-2.12/cats/instances/all.scala | 4 +- .../scala-2.12/cats/instances/package.scala | 2 +- .../cats/data/NonEmptyLazyList.scala | 10 +- .../scala-2.13+/cats/data/ZipLazyList.scala | 2 +- .../scala-2.13+/cats/data/ZipStream.scala | 2 +- .../main/scala-2.13+/cats/instances/all.scala | 4 +- .../scala-2.13+/cats/instances/arraySeq.scala | 4 +- .../scala-2.13+/cats/instances/lazyList.scala | 3 +- .../scala-2.13+/cats/instances/package.scala | 2 +- .../scala-2.13+/cats/instances/stream.scala | 7 +- core/src/main/scala/cats/Applicative.scala | 4 +- core/src/main/scala/cats/Apply.scala | 1 + core/src/main/scala/cats/Composed.scala | 31 ++-- core/src/main/scala/cats/Eval.scala | 4 +- core/src/main/scala/cats/FlatMap.scala | 2 + core/src/main/scala/cats/Foldable.scala | 2 + .../main/scala/cats/NonEmptyReducible.scala | 10 +- core/src/main/scala/cats/Parallel.scala | 2 +- core/src/main/scala/cats/Representable.scala | 4 +- core/src/main/scala/cats/Semigroupal.scala | 2 +- .../cats/data/AbstractNonEmptyInstances.scala | 10 +- core/src/main/scala/cats/data/AndThen.scala | 2 +- core/src/main/scala/cats/data/Chain.scala | 8 +- core/src/main/scala/cats/data/Cokleisli.scala | 4 +- core/src/main/scala/cats/data/Const.scala | 9 +- core/src/main/scala/cats/data/ContT.scala | 2 +- core/src/main/scala/cats/data/EitherK.scala | 2 +- core/src/main/scala/cats/data/EitherT.scala | 13 +- core/src/main/scala/cats/data/Func.scala | 11 +- core/src/main/scala/cats/data/IdT.scala | 12 +- .../cats/data/IndexedReaderWriterStateT.scala | 14 +- .../main/scala/cats/data/IndexedStateT.scala | 5 +- core/src/main/scala/cats/data/Ior.scala | 6 +- core/src/main/scala/cats/data/IorT.scala | 22 ++- core/src/main/scala/cats/data/Kleisli.scala | 26 +-- core/src/main/scala/cats/data/Nested.scala | 28 +-- .../main/scala/cats/data/NonEmptyChain.scala | 8 +- .../main/scala/cats/data/NonEmptyList.scala | 8 +- .../scala/cats/data/NonEmptyMapImpl.scala | 5 +- .../main/scala/cats/data/NonEmptySeq.scala | 8 +- .../main/scala/cats/data/NonEmptyVector.scala | 8 +- core/src/main/scala/cats/data/OneAnd.scala | 4 +- core/src/main/scala/cats/data/OptionT.scala | 10 +- .../scala/cats/data/RepresentableStoreT.scala | 4 +- core/src/main/scala/cats/data/Tuple2K.scala | 23 +-- core/src/main/scala/cats/data/Validated.scala | 7 +- core/src/main/scala/cats/data/WriterT.scala | 41 +++-- core/src/main/scala/cats/data/ZipList.scala | 3 +- core/src/main/scala/cats/data/ZipSeq.scala | 3 +- core/src/main/scala/cats/data/ZipVector.scala | 3 +- core/src/main/scala/cats/implicits.scala | 4 +- .../main/scala/cats/instances/anyval.scala | 2 + .../main/scala/cats/instances/either.scala | 6 +- .../main/scala/cats/instances/function.scala | 4 +- .../main/scala/cats/instances/future.scala | 13 +- core/src/main/scala/cats/instances/list.scala | 8 +- core/src/main/scala/cats/instances/map.scala | 2 +- .../main/scala/cats/instances/option.scala | 3 +- .../src/main/scala/cats/instances/queue.scala | 7 +- core/src/main/scala/cats/instances/seq.scala | 7 +- .../main/scala/cats/instances/sortedMap.scala | 2 +- .../main/scala/cats/instances/sortedSet.scala | 2 +- .../main/scala/cats/instances/tailrec.scala | 2 +- core/src/main/scala/cats/instances/try.scala | 4 +- .../src/main/scala/cats/instances/tuple.scala | 5 +- .../main/scala/cats/instances/vector.scala | 7 +- core/src/main/scala/cats/package.scala | 7 +- free/src/main/scala/cats/free/Cofree.scala | 10 +- free/src/main/scala/cats/free/Free.scala | 6 +- .../scala/cats/free/FreeApplicative.scala | 2 +- free/src/main/scala/cats/free/FreeT.scala | 15 +- .../cats/free/FreeStructuralSuite.scala | 5 +- .../cats/laws/NonEmptyTraverseLaws.scala | 2 +- .../scala/cats/laws/ShortCircuitingLaws.scala | 6 +- .../main/scala/cats/laws/TraverseLaws.scala | 2 +- .../cats/laws/UnorderedTraverseLaws.scala | 2 +- mima.sbt | 159 +++++++++--------- project/TupleMonadInstancesBoiler.scala | 2 +- ...upleUnorderedFoldableInstancesBoiler.scala | 2 +- .../main/scala/cats/tests/ListWrapper.scala | 6 +- .../test/scala/cats/js/instances/future.scala | 3 +- .../cats/tests/ScalaVersionSpecific.scala | 2 +- .../cats/tests/ApplicativeErrorSuite.scala | 4 +- .../test/scala/cats/tests/FoldableSuite.scala | 2 +- .../test/scala/cats/tests/ParallelSuite.scala | 4 +- .../scala/cats/tests/ReducibleSuite.scala | 2 +- .../scala/cats/tests/RegressionSuite.scala | 2 +- .../test/scala/cats/tests/TraverseSuite.scala | 2 +- 88 files changed, 445 insertions(+), 291 deletions(-) diff --git a/core/src/main/scala-2.12/cats/instances/all.scala b/core/src/main/scala-2.12/cats/instances/all.scala index 1628094e95..d7451b2cdf 100644 --- a/core/src/main/scala-2.12/cats/instances/all.scala +++ b/core/src/main/scala-2.12/cats/instances/all.scala @@ -23,7 +23,7 @@ package cats package instances abstract class AllInstancesBinCompat - extends AllInstances + extends AbstractAllInstances with AllInstancesBinCompat0 with AllInstancesBinCompat1 with AllInstancesBinCompat2 @@ -34,6 +34,8 @@ abstract class AllInstancesBinCompat with AllInstancesBinCompat7 with AllInstancesBinCompat8 +abstract private[cats] class AbstractAllInstances extends AbstractAnyValInstances with AllInstances + trait AllInstances extends AnyValInstances with BigIntInstances diff --git a/core/src/main/scala-2.12/cats/instances/package.scala b/core/src/main/scala-2.12/cats/instances/package.scala index 1c54805005..35b41d9b0e 100644 --- a/core/src/main/scala-2.12/cats/instances/package.scala +++ b/core/src/main/scala-2.12/cats/instances/package.scala @@ -77,7 +77,7 @@ package object instances { object string extends StringInstances object tailRec extends TailRecInstances object try_ extends TryInstances - object tuple extends TupleInstances with Tuple2InstancesBinCompat0 + object tuple extends AbstractTupleInstances with Tuple2InstancesBinCompat0 object unit extends UnitInstances object uuid extends UUIDInstances object vector extends VectorInstances with VectorInstancesBinCompat0 diff --git a/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala b/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala index 20844893ad..79ae084254 100644 --- a/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala +++ b/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala @@ -514,9 +514,10 @@ sealed abstract private[data] class NonEmptyLazyListInstances extends NonEmptyLa NonEmptyLazyList ] & NonEmptyAlternative[NonEmptyLazyList] & Align[NonEmptyLazyList] = new AbstractNonEmptyInstances[LazyList, NonEmptyLazyList] with Align[NonEmptyLazyList] { - def extract[A](fa: NonEmptyLazyList[A]): A = fa.head + override def split[A](fa: NonEmptyLazyList[A]): (A, LazyList[A]) = (fa.head, fa.tail) + def nonEmptyTraverse[G[_]: Apply, A, B](fa: NonEmptyLazyList[A])(f: A => G[B]): G[NonEmptyLazyList[B]] = { def loop(head: A, tail: LazyList[A]): Eval[G[NonEmptyLazyList[B]]] = tail.headOption.fold(Eval.now(Apply[G].map(f(head))(NonEmptyLazyList(_)))) { h => @@ -526,9 +527,12 @@ sealed abstract private[data] class NonEmptyLazyListInstances extends NonEmptyLa loop(fa.head, fa.tail).value } - def reduceLeftTo[A, B](fa: NonEmptyLazyList[A])(f: A => B)(g: (B, A) => B): B = fa.reduceLeftTo(f)(g) + override def reduceLeftTo[A, B](fa: NonEmptyLazyList[A])(f: A => B)(g: (B, A) => B): B = + fa.reduceLeftTo(f)(g) - def reduceRightTo[A, B](fa: NonEmptyLazyList[A])(f: A => B)(g: (A, cats.Eval[B]) => cats.Eval[B]): cats.Eval[B] = + override def reduceRightTo[A, B]( + fa: NonEmptyLazyList[A] + )(f: A => B)(g: (A, cats.Eval[B]) => cats.Eval[B]): cats.Eval[B] = fa.tail match { case head +: tail => val nell = NonEmptyLazyList.fromLazyListPrepend(head, tail) diff --git a/core/src/main/scala-2.13+/cats/data/ZipLazyList.scala b/core/src/main/scala-2.13+/cats/data/ZipLazyList.scala index 0f5d552636..4ab9fff545 100644 --- a/core/src/main/scala-2.13+/cats/data/ZipLazyList.scala +++ b/core/src/main/scala-2.13+/cats/data/ZipLazyList.scala @@ -29,7 +29,7 @@ object ZipLazyList { def apply[A](value: LazyList[A]): ZipLazyList[A] = new ZipLazyList(value) implicit val catsDataAlternativeForZipLazyList: Alternative[ZipLazyList] & CommutativeApplicative[ZipLazyList] = - new Alternative[ZipLazyList] with CommutativeApplicative[ZipLazyList] { + new Apply.AbstractApply[ZipLazyList] with Alternative[ZipLazyList] with CommutativeApplicative[ZipLazyList] { def pure[A](x: A): ZipLazyList[A] = new ZipLazyList(LazyList.continually(x)) override def map[A, B](fa: ZipLazyList[A])(f: (A) => B): ZipLazyList[B] = diff --git a/core/src/main/scala-2.13+/cats/data/ZipStream.scala b/core/src/main/scala-2.13+/cats/data/ZipStream.scala index 1f80ceef78..e443953e61 100644 --- a/core/src/main/scala-2.13+/cats/data/ZipStream.scala +++ b/core/src/main/scala-2.13+/cats/data/ZipStream.scala @@ -31,7 +31,7 @@ object ZipStream { def apply[A](value: Stream[A]): ZipStream[A] = new ZipStream(value) implicit val catsDataAlternativeForZipStream: Alternative[ZipStream] & CommutativeApplicative[ZipStream] = - new Alternative[ZipStream] with CommutativeApplicative[ZipStream] { + new Apply.AbstractApply[ZipStream] with Alternative[ZipStream] with CommutativeApplicative[ZipStream] { def pure[A](x: A): ZipStream[A] = new ZipStream(Stream.continually(x)) override def map[A, B](fa: ZipStream[A])(f: (A) => B): ZipStream[B] = diff --git a/core/src/main/scala-2.13+/cats/instances/all.scala b/core/src/main/scala-2.13+/cats/instances/all.scala index f57d80ac52..0aeef1cba8 100644 --- a/core/src/main/scala-2.13+/cats/instances/all.scala +++ b/core/src/main/scala-2.13+/cats/instances/all.scala @@ -23,7 +23,7 @@ package cats package instances abstract class AllInstancesBinCompat - extends AllInstances + extends AbstractAllInstances with AllInstancesBinCompat0 with AllInstancesBinCompat1 with AllInstancesBinCompat2 @@ -35,6 +35,8 @@ abstract class AllInstancesBinCompat with AllInstancesBinCompat8 with AllInstancesBinCompat9 +abstract private[cats] class AbstractAllInstances extends AbstractAnyValInstances with AllInstances + trait AllInstances extends AnyValInstances with ArraySeqInstances diff --git a/core/src/main/scala-2.13+/cats/instances/arraySeq.scala b/core/src/main/scala-2.13+/cats/instances/arraySeq.scala index 232d5f3a02..a3402bd29d 100644 --- a/core/src/main/scala-2.13+/cats/instances/arraySeq.scala +++ b/core/src/main/scala-2.13+/cats/instances/arraySeq.scala @@ -42,11 +42,13 @@ trait ArraySeqInstances extends cats.kernel.instances.ArraySeqInstances { private[cats] object ArraySeqInstances { final private val stdInstances : Traverse[ArraySeq] & Monad[ArraySeq] & Alternative[ArraySeq] & CoflatMap[ArraySeq] & Align[ArraySeq] = - new Traverse[ArraySeq] + new FlatMap.FoldableFlatMap[ArraySeq] + with Traverse[ArraySeq] with Monad[ArraySeq] with Alternative[ArraySeq] with CoflatMap[ArraySeq] with Align[ArraySeq] { + def empty[A]: ArraySeq[A] = ArraySeq.untagged.empty diff --git a/core/src/main/scala-2.13+/cats/instances/lazyList.scala b/core/src/main/scala-2.13+/cats/instances/lazyList.scala index 25aaa0ba9f..41586358db 100644 --- a/core/src/main/scala-2.13+/cats/instances/lazyList.scala +++ b/core/src/main/scala-2.13+/cats/instances/lazyList.scala @@ -35,7 +35,8 @@ trait LazyListInstances extends cats.kernel.instances.LazyListInstances { implicit val catsStdInstancesForLazyList : Traverse[LazyList] & Alternative[LazyList] & Monad[LazyList] & CoflatMap[LazyList] & Align[LazyList] = - new Traverse[LazyList] + new FlatMap.FoldableFlatMap[LazyList] + with Traverse[LazyList] with Alternative[LazyList] with Monad[LazyList] with CoflatMap[LazyList] diff --git a/core/src/main/scala-2.13+/cats/instances/package.scala b/core/src/main/scala-2.13+/cats/instances/package.scala index 2ee72b37db..7b0cfaac02 100644 --- a/core/src/main/scala-2.13+/cats/instances/package.scala +++ b/core/src/main/scala-2.13+/cats/instances/package.scala @@ -81,7 +81,7 @@ package object instances { object string extends StringInstances object tailRec extends TailRecInstances object try_ extends TryInstances - object tuple extends TupleInstances with Tuple2InstancesBinCompat0 + object tuple extends AbstractTupleInstances with Tuple2InstancesBinCompat0 object unit extends UnitInstances object uuid extends UUIDInstances object vector extends VectorInstances with VectorInstancesBinCompat0 diff --git a/core/src/main/scala-2.13+/cats/instances/stream.scala b/core/src/main/scala-2.13+/cats/instances/stream.scala index eccaaf032e..9985651a2a 100644 --- a/core/src/main/scala-2.13+/cats/instances/stream.scala +++ b/core/src/main/scala-2.13+/cats/instances/stream.scala @@ -34,7 +34,12 @@ trait StreamInstances extends cats.kernel.instances.StreamInstances { @deprecated("Use cats.instances.lazyList", "2.0.0-RC2") implicit val catsStdInstancesForStream : Traverse[Stream] & Alternative[Stream] & Monad[Stream] & CoflatMap[Stream] & Align[Stream] = - new Traverse[Stream] with Alternative[Stream] with Monad[Stream] with CoflatMap[Stream] with Align[Stream] { + new FlatMap.FoldableFlatMap[Stream] + with Traverse[Stream] + with Alternative[Stream] + with Monad[Stream] + with CoflatMap[Stream] + with Align[Stream] { def empty[A]: Stream[A] = Stream.Empty diff --git a/core/src/main/scala/cats/Applicative.scala b/core/src/main/scala/cats/Applicative.scala index 7a6c267612..a85e720e15 100644 --- a/core/src/main/scala/cats/Applicative.scala +++ b/core/src/main/scala/cats/Applicative.scala @@ -352,7 +352,9 @@ private[cats] class ApplicativeMonoid[F[_], A](f: Applicative[F], monoid: Monoid def empty: F[A] = f.pure(monoid.empty) } -private[cats] class ArrowApplicative[F[_, _], A](F: Arrow[F]) extends Applicative[F[A, *]] { +private[cats] class ArrowApplicative[F[_, _], A](F: Arrow[F]) + extends Apply.AbstractApply[F[A, *]] + with Applicative[F[A, *]] { def pure[B](b: B): F[A, B] = F.lift[A, B](_ => b) override def map[B, C](fb: F[A, B])(f: B => C): F[A, C] = F.rmap(fb)(f) def ap[B, C](ff: F[A, B => C])(fb: F[A, B]): F[A, C] = diff --git a/core/src/main/scala/cats/Apply.scala b/core/src/main/scala/cats/Apply.scala index f4ffa1f7f3..f153632841 100644 --- a/core/src/main/scala/cats/Apply.scala +++ b/core/src/main/scala/cats/Apply.scala @@ -249,6 +249,7 @@ trait Apply[F[_]] extends Functor[F] with InvariantSemigroupal[F] with ApplyArit } object Apply { + abstract private[cats] class AbstractApply[F[_]] extends Apply[F] /** * This semigroup uses a product operation to combine `F`s. diff --git a/core/src/main/scala/cats/Composed.scala b/core/src/main/scala/cats/Composed.scala index 42dcb46b72..b20cf3b419 100644 --- a/core/src/main/scala/cats/Composed.scala +++ b/core/src/main/scala/cats/Composed.scala @@ -54,7 +54,8 @@ private[cats] trait ComposedFunctorBifunctor[F[_], G[_, _]] extends Bifunctor[λ F.map(fab)(G.bimap(_)(f, g)) } -private[cats] trait ComposedApply[F[_], G[_]] extends Apply[λ[α => F[G[α]]]] with ComposedFunctor[F, G] { outer => +private[cats] trait ComposedApply[F[_], G[_]] extends Apply.AbstractApply[λ[α => F[G[α]]]] with ComposedFunctor[F, G] { + outer => def F: Apply[F] def G: Apply[G] @@ -65,7 +66,7 @@ private[cats] trait ComposedApply[F[_], G[_]] extends Apply[λ[α => F[G[α]]]] F.map2(fga, fgb)(G.product) } -private[cats] trait ComposedApplicative[F[_], G[_]] extends Applicative[λ[α => F[G[α]]]] with ComposedApply[F, G] { +private[cats] trait ComposedApplicative[F[_], G[_]] extends ComposedApply[F, G] with Applicative[λ[α => F[G[α]]]] { outer => def F: Applicative[F] def G: Applicative[G] @@ -87,17 +88,17 @@ private[cats] trait ComposedMonoidK[F[_], G[_]] extends MonoidK[λ[α => F[G[α] } private[cats] trait ComposedNonEmptyAlternative[F[_], G[_]] - extends NonEmptyAlternative[λ[α => F[G[α]]]] - with ComposedApplicative[F, G] - with ComposedSemigroupK[F, G] { outer => + extends ComposedApplicative[F, G] + with ComposedSemigroupK[F, G] + with NonEmptyAlternative[λ[α => F[G[α]]]] { outer => def F: NonEmptyAlternative[F] } private[cats] trait ComposedAlternative[F[_], G[_]] - extends Alternative[λ[α => F[G[α]]]] - with ComposedNonEmptyAlternative[F, G] - with ComposedMonoidK[F, G] { outer => + extends ComposedNonEmptyAlternative[F, G] + with ComposedMonoidK[F, G] + with Alternative[λ[α => F[G[α]]]] { outer => def F: Alternative[F] @@ -106,7 +107,7 @@ private[cats] trait ComposedAlternative[F[_], G[_]] override def appendK[A](fa: F[G[A]], a: A): F[G[A]] = F.appendK(fa, G.pure(a)) } -private[cats] trait ComposedFoldable[F[_], G[_]] extends Foldable[λ[α => F[G[α]]]] { outer => +private[cats] trait ComposedFoldable[F[_], G[_]] extends Foldable.AbstractFoldable[λ[α => F[G[α]]]] { outer => def F: Foldable[F] def G: Foldable[G] @@ -124,9 +125,9 @@ private[cats] trait ComposedFoldable[F[_], G[_]] extends Foldable[λ[α => F[G[ } private[cats] trait ComposedTraverse[F[_], G[_]] - extends Traverse[λ[α => F[G[α]]]] - with ComposedFoldable[F, G] - with ComposedFunctor[F, G] { + extends ComposedFoldable[F, G] + with ComposedFunctor[F, G] + with Traverse[λ[α => F[G[α]]]] { def F: Traverse[F] def G: Traverse[G] @@ -138,9 +139,9 @@ private[cats] trait ComposedTraverse[F[_], G[_]] } private[cats] trait ComposedNonEmptyTraverse[F[_], G[_]] - extends NonEmptyTraverse[λ[α => F[G[α]]]] + extends ComposedReducible[F, G] with ComposedTraverse[F, G] - with ComposedReducible[F, G] { + with NonEmptyTraverse[λ[α => F[G[α]]]] { def F: NonEmptyTraverse[F] def G: NonEmptyTraverse[G] @@ -148,7 +149,7 @@ private[cats] trait ComposedNonEmptyTraverse[F[_], G[_]] F.nonEmptyTraverse(fga)(ga => G.nonEmptyTraverse(ga)(f)) } -private[cats] trait ComposedReducible[F[_], G[_]] extends Reducible[λ[α => F[G[α]]]] with ComposedFoldable[F, G] { +private[cats] trait ComposedReducible[F[_], G[_]] extends ComposedFoldable[F, G] with Reducible[λ[α => F[G[α]]]] { outer => def F: Reducible[F] def G: Reducible[G] diff --git a/core/src/main/scala/cats/Eval.scala b/core/src/main/scala/cats/Eval.scala index 3e4a36682e..f3b4f6776d 100644 --- a/core/src/main/scala/cats/Eval.scala +++ b/core/src/main/scala/cats/Eval.scala @@ -390,7 +390,7 @@ object Eval extends EvalInstances { sealed abstract private[cats] class EvalInstances extends EvalInstances0 { implicit val catsBimonadForEval: Bimonad[Eval] & CommutativeMonad[Eval] = - new Bimonad[Eval] with StackSafeMonad[Eval] with CommutativeMonad[Eval] { + new FlatMap.AbstractFlatMap[Eval] with Bimonad[Eval] with StackSafeMonad[Eval] with CommutativeMonad[Eval] { override def map[A, B](fa: Eval[A])(f: A => B): Eval[B] = fa.map(f) def pure[A](a: A): Eval[A] = Now(a) def flatMap[A, B](fa: Eval[A])(f: A => Eval[B]): Eval[B] = fa.flatMap(f) @@ -407,7 +407,7 @@ sealed abstract private[cats] class EvalInstances extends EvalInstances0 { } implicit val catsReducibleForEval: Reducible[Eval] = - new Reducible[Eval] { + new Foldable.AbstractFoldable[Eval] with Reducible[Eval] { def foldLeft[A, B](fa: Eval[A], b: B)(f: (B, A) => B): B = f(b, fa.value) def foldRight[A, B](fa: Eval[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = diff --git a/core/src/main/scala/cats/FlatMap.scala b/core/src/main/scala/cats/FlatMap.scala index 1adeb60fa3..335815db2d 100644 --- a/core/src/main/scala/cats/FlatMap.scala +++ b/core/src/main/scala/cats/FlatMap.scala @@ -220,6 +220,8 @@ trait FlatMap[F[_]] extends Apply[F] with FlatMapArityFunctions[F] { } object FlatMap { + abstract private[cats] class AbstractFlatMap[F[_]] extends Apply.AbstractApply[F] with FlatMap[F] + abstract private[cats] class FoldableFlatMap[F[_]] extends AbstractFlatMap[F] with Foldable[F] /** * Summon an instance of [[FlatMap]] for `F`. diff --git a/core/src/main/scala/cats/Foldable.scala b/core/src/main/scala/cats/Foldable.scala index 70db2e7cd3..d83c8bb550 100644 --- a/core/src/main/scala/cats/Foldable.scala +++ b/core/src/main/scala/cats/Foldable.scala @@ -963,6 +963,8 @@ trait Foldable[F[_]] extends UnorderedFoldable[F] with FoldableNFunctions[F] { s } object Foldable { + abstract private[cats] class AbstractFoldable[F[_]] extends Foldable[F] + private val sentinel: Function1[Any, Any] = new scala.runtime.AbstractFunction1[Any, Any] { def apply(a: Any): Any = this } diff --git a/core/src/main/scala/cats/NonEmptyReducible.scala b/core/src/main/scala/cats/NonEmptyReducible.scala index 82e5e1ae48..62ef5df5d8 100644 --- a/core/src/main/scala/cats/NonEmptyReducible.scala +++ b/core/src/main/scala/cats/NonEmptyReducible.scala @@ -34,7 +34,15 @@ import cats.data.NonEmptyList * This class is only a helper, does not define a typeclass and should not be used outside of Cats. * Also see the discussion: PR #3541 and issue #3069. */ -abstract class NonEmptyReducible[F[_], G[_]](implicit G: Foldable[G]) extends Reducible[F] { +abstract class NonEmptyReducible[F[_], G[_]](implicit foldable: Foldable[G]) + extends Foldable.AbstractFoldable[F] + with NonEmptyReducibleTrait[F, G] { + final protected[cats] def G: Foldable[G] = foldable +} + +private[cats] trait NonEmptyReducibleTrait[F[_], G[_]] extends Reducible[F] { + implicit protected[cats] def G: Foldable[G] + def split[A](fa: F[A]): (A, G[A]) def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B = { diff --git a/core/src/main/scala/cats/Parallel.scala b/core/src/main/scala/cats/Parallel.scala index 6d00b28194..48babeae3d 100644 --- a/core/src/main/scala/cats/Parallel.scala +++ b/core/src/main/scala/cats/Parallel.scala @@ -100,7 +100,7 @@ trait Parallel[M[_]] extends NonEmptyParallel[M] { * then you can get `ApplicativeError[F, E]` from `MonadError[M, E]`. */ def applicativeError[E](implicit E: MonadError[M, E]): ApplicativeError[F, E] = - new ApplicativeError[F, E] { + new Apply.AbstractApply[F] with ApplicativeError[F, E] { def raiseError[A](e: E): F[A] = parallel(MonadError[M, E].raiseError(e)) diff --git a/core/src/main/scala/cats/Representable.scala b/core/src/main/scala/cats/Representable.scala index 862d5d52bf..1d073f8c1f 100644 --- a/core/src/main/scala/cats/Representable.scala +++ b/core/src/main/scala/cats/Representable.scala @@ -103,7 +103,7 @@ trait Representable[F[_]] extends Serializable { self => } } -private trait RepresentableMonad[F[_], R] extends Monad[F] { +abstract private class RepresentableMonad[F[_], R] extends FlatMap.AbstractFlatMap[F] with Monad[F] { def R: Representable.Aux[F, R] @@ -125,7 +125,7 @@ private trait RepresentableMonad[F[_], R] extends Monad[F] { } } -private trait RepresentableBimonad[F[_], R] extends RepresentableMonad[F, R] with Bimonad[F] { +abstract private class RepresentableBimonad[F[_], R] extends RepresentableMonad[F, R] with Bimonad[F] { def M: Monoid[R] diff --git a/core/src/main/scala/cats/Semigroupal.scala b/core/src/main/scala/cats/Semigroupal.scala index 3a7f64a63c..246175bff7 100644 --- a/core/src/main/scala/cats/Semigroupal.scala +++ b/core/src/main/scala/cats/Semigroupal.scala @@ -66,7 +66,7 @@ trait Semigroupal[F[_]] extends Serializable { def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] } -object Semigroupal extends ScalaVersionSpecificSemigroupalInstances with SemigroupalArityFunctions { +object Semigroupal extends SemigroupalArityFunctions with ScalaVersionSpecificSemigroupalInstances { implicit def catsSemigroupalForId: Semigroupal[Id] = catsInstancesForId implicit def catsSemigroupalForOption: Semigroupal[Option] = cats.instances.option.catsStdInstancesForOption implicit def catsSemigroupalForTry: Semigroupal[Try] = cats.instances.try_.catsStdInstancesForTry diff --git a/core/src/main/scala/cats/data/AbstractNonEmptyInstances.scala b/core/src/main/scala/cats/data/AbstractNonEmptyInstances.scala index dba28aa712..735ecfac21 100644 --- a/core/src/main/scala/cats/data/AbstractNonEmptyInstances.scala +++ b/core/src/main/scala/cats/data/AbstractNonEmptyInstances.scala @@ -27,9 +27,13 @@ abstract private[data] class AbstractNonEmptyInstances[F[_], NonEmptyF[_]](impli CF: CoflatMap[F], TF: Traverse[F], SF: Alternative[F] -) extends Bimonad[NonEmptyF] +) extends FlatMap.FoldableFlatMap[NonEmptyF] + with NonEmptyReducibleTrait[NonEmptyF, F] + with Bimonad[NonEmptyF] with NonEmptyTraverse[NonEmptyF] with NonEmptyAlternative[NonEmptyF] { + + override def G: Foldable[F] = TF val monadInstance = MF.asInstanceOf[Monad[NonEmptyF]] val coflatMapInstance = CF.asInstanceOf[CoflatMap[NonEmptyF]] val traverseInstance = Traverse[F].asInstanceOf[Traverse[NonEmptyF]] @@ -63,10 +67,10 @@ abstract private[data] class AbstractNonEmptyInstances[F[_], NonEmptyF[_]](impli def tailRecM[A, B](a: A)(f: A => NonEmptyF[Either[A, B]]): NonEmptyF[B] = monadInstance.tailRecM(a)(f) - def foldLeft[A, B](fa: NonEmptyF[A], b: B)(f: (B, A) => B): B = + override def foldLeft[A, B](fa: NonEmptyF[A], b: B)(f: (B, A) => B): B = traverseInstance.foldLeft(fa, b)(f) - def foldRight[A, B](fa: NonEmptyF[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = + override def foldRight[A, B](fa: NonEmptyF[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = traverseInstance.foldRight(fa, lb)(f) override def foldMap[A, B](fa: NonEmptyF[A])(f: A => B)(implicit B: Monoid[B]): B = diff --git a/core/src/main/scala/cats/data/AndThen.scala b/core/src/main/scala/cats/data/AndThen.scala index 6e813ccb19..05639733cd 100644 --- a/core/src/main/scala/cats/data/AndThen.scala +++ b/core/src/main/scala/cats/data/AndThen.scala @@ -270,7 +270,7 @@ abstract private[data] class AndThenInstances0 extends AndThenInstances1 { * [[cats.Monad]] instance for [[AndThen]]. */ implicit def catsDataMonadForAndThen[T]: Monad[AndThen[T, *]] = - new Monad[AndThen[T, *]] { + new FlatMap.AbstractFlatMap[AndThen[T, *]] with Monad[AndThen[T, *]] { // Piggybacking on the instance for Function1 private[this] val fn1 = instances.all.catsStdMonadForFunction1[T] diff --git a/core/src/main/scala/cats/data/Chain.scala b/core/src/main/scala/cats/data/Chain.scala index a191daaaaf..9fdbe49277 100644 --- a/core/src/main/scala/cats/data/Chain.scala +++ b/core/src/main/scala/cats/data/Chain.scala @@ -1397,7 +1397,13 @@ sealed abstract private[data] class ChainInstances extends ChainInstances1 { implicit val catsDataInstancesForChain : Traverse[Chain] & Alternative[Chain] & Monad[Chain] & CoflatMap[Chain] & Align[Chain] = - new Traverse[Chain] with Alternative[Chain] with Monad[Chain] with CoflatMap[Chain] with Align[Chain] { + new FlatMap.FoldableFlatMap[Chain] + with Traverse[Chain] + with Alternative[Chain] + with Monad[Chain] + with CoflatMap[Chain] + with Align[Chain] { + def foldLeft[A, B](fa: Chain[A], b: B)(f: (B, A) => B): B = fa.foldLeft(b)(f) def foldRight[A, B](fa: Chain[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = { diff --git a/core/src/main/scala/cats/data/Cokleisli.scala b/core/src/main/scala/cats/data/Cokleisli.scala index 48884fc253..e86f1becdc 100644 --- a/core/src/main/scala/cats/data/Cokleisli.scala +++ b/core/src/main/scala/cats/data/Cokleisli.scala @@ -132,7 +132,9 @@ sealed abstract private[data] class CokleisliInstances1 { } } -private[data] class CokleisliMonad[F[_], A] extends Monad[Cokleisli[F, A, *]] { +private[data] class CokleisliMonad[F[_], A] + extends FlatMap.AbstractFlatMap[Cokleisli[F, A, *]] + with Monad[Cokleisli[F, A, *]] { def pure[B](x: B): Cokleisli[F, A, B] = Cokleisli.pure(x) diff --git a/core/src/main/scala/cats/data/Const.scala b/core/src/main/scala/cats/data/Const.scala index 967099acbc..4d620a78b0 100644 --- a/core/src/main/scala/cats/data/Const.scala +++ b/core/src/main/scala/cats/data/Const.scala @@ -244,7 +244,7 @@ sealed abstract private[data] class ConstInstances3 extends ConstInstances4 { sealed abstract private[data] class ConstInstances4 sealed private[data] trait ConstFunctor[C] extends Functor[Const[C, *]] { - final override def map[A, B](fa: Const[C, A])(f: A => B): Const[C, B] = + override def map[A, B](fa: Const[C, A])(f: A => B): Const[C, B] = fa.retag[B] } @@ -253,7 +253,7 @@ sealed private[data] trait ConstContravariant[C] extends Contravariant[Const[C, fa.retag[B] } -sealed private[data] trait ConstApply[C] extends ConstFunctor[C] with Apply[Const[C, *]] { +sealed private[data] trait ConstApply[C] extends Apply.AbstractApply[Const[C, *]] with ConstFunctor[C] { implicit def C0: Semigroup[C] @@ -264,10 +264,13 @@ sealed private[data] trait ConstApply[C] extends ConstFunctor[C] with Apply[Cons fa.retag[(A, B)].combine(fb.retag[(A, B)]) } -sealed private[data] trait ConstApplicative[C] extends Applicative[Const[C, *]] with ConstApply[C] { +sealed private[data] trait ConstApplicative[C] extends ConstApply[C] with Applicative[Const[C, *]] { implicit def C0: Monoid[C] def pure[A](x: A): Const[C, A] = Const.empty + + final override def map[A, B](fa: Const[C, A])(f: A => B): Const[C, B] = + super[ConstApply].map(fa)(f) } diff --git a/core/src/main/scala/cats/data/ContT.scala b/core/src/main/scala/cats/data/ContT.scala index 669aa4cbcf..6d260f5d9c 100644 --- a/core/src/main/scala/cats/data/ContT.scala +++ b/core/src/main/scala/cats/data/ContT.scala @@ -281,7 +281,7 @@ object ContT { } implicit def catsDataContTMonad[M[_]: Defer, A]: Monad[ContT[M, A, *]] = - new Monad[ContT[M, A, *]] { + new FlatMap.AbstractFlatMap[ContT[M, A, *]] with Monad[ContT[M, A, *]] { def pure[B](b: B): ContT[M, A, B] = ContT.pure(b) diff --git a/core/src/main/scala/cats/data/EitherK.scala b/core/src/main/scala/cats/data/EitherK.scala index 2607b6e995..f462a8c8a1 100644 --- a/core/src/main/scala/cats/data/EitherK.scala +++ b/core/src/main/scala/cats/data/EitherK.scala @@ -238,7 +238,7 @@ private[data] trait EitherKContravariant[F[_], G[_]] extends Contravariant[Eithe a.contramap(f) } -private[data] trait EitherKFoldable[F[_], G[_]] extends Foldable[EitherK[F, G, *]] { +private[data] trait EitherKFoldable[F[_], G[_]] extends Foldable.AbstractFoldable[EitherK[F, G, *]] { implicit def F: Foldable[F] implicit def G: Foldable[G] diff --git a/core/src/main/scala/cats/data/EitherT.scala b/core/src/main/scala/cats/data/EitherT.scala index 0f4f5108f6..9339255a75 100644 --- a/core/src/main/scala/cats/data/EitherT.scala +++ b/core/src/main/scala/cats/data/EitherT.scala @@ -1201,7 +1201,10 @@ private[data] trait EitherTFunctor[F[_], L] extends Functor[EitherT[F, L, *]] { override def map[A, B](fa: EitherT[F, L, A])(f: A => B): EitherT[F, L, B] = fa.map(f) } -private[data] trait EitherTMonad[F[_], L] extends Monad[EitherT[F, L, *]] with EitherTFunctor[F, L] { +private[data] trait EitherTMonad[F[_], L] + extends FlatMap.AbstractFlatMap[EitherT[F, L, *]] + with Monad[EitherT[F, L, *]] + with EitherTFunctor[F, L] { implicit val F: Monad[F] def pure[A](a: A): EitherT[F, L, A] = EitherT.pure(a) @@ -1218,7 +1221,7 @@ private[data] trait EitherTMonad[F[_], L] extends Monad[EitherT[F, L, *]] with E ) } -private[data] trait EitherTMonadErrorF[F[_], E, L] extends MonadError[EitherT[F, L, *], E] with EitherTMonad[F, L] { +private[data] trait EitherTMonadErrorF[F[_], E, L] extends EitherTMonad[F, L] with MonadError[EitherT[F, L, *], E] { implicit val F: MonadError[F, E] def handleErrorWith[A](fea: EitherT[F, L, A])(f: E => EitherT[F, L, A]): EitherT[F, L, A] = @@ -1227,7 +1230,7 @@ private[data] trait EitherTMonadErrorF[F[_], E, L] extends MonadError[EitherT[F, def raiseError[A](e: E): EitherT[F, L, A] = EitherT(F.raiseError(e)) } -private[data] trait EitherTMonadError[F[_], L] extends MonadError[EitherT[F, L, *], L] with EitherTMonad[F, L] { +private[data] trait EitherTMonadError[F[_], L] extends EitherTMonad[F, L] with MonadError[EitherT[F, L, *], L] { def handleErrorWith[A](fea: EitherT[F, L, A])(f: L => EitherT[F, L, A]): EitherT[F, L, A] = EitherT(F.flatMap(fea.value) { case Left(e) => f(e).value @@ -1246,7 +1249,7 @@ private[data] trait EitherTMonadError[F[_], L] extends MonadError[EitherT[F, L, fla.recoverWith(pf) } -sealed private[data] trait EitherTFoldable[F[_], L] extends Foldable[EitherT[F, L, *]] { +sealed private[data] trait EitherTFoldable[F[_], L] extends Foldable.AbstractFoldable[EitherT[F, L, *]] { implicit def F0: Foldable[F] def foldLeft[A, B](fa: EitherT[F, L, A], b: B)(f: (B, A) => B): B = @@ -1256,7 +1259,7 @@ sealed private[data] trait EitherTFoldable[F[_], L] extends Foldable[EitherT[F, fa.foldRight(lb)(f) } -sealed private[data] trait EitherTTraverse[F[_], L] extends Traverse[EitherT[F, L, *]] with EitherTFoldable[F, L] { +sealed private[data] trait EitherTTraverse[F[_], L] extends EitherTFoldable[F, L] with Traverse[EitherT[F, L, *]] { implicit override def F0: Traverse[F] override def traverse[G[_]: Applicative, A, B](fa: EitherT[F, L, A])(f: A => G[B]): G[EitherT[F, L, B]] = diff --git a/core/src/main/scala/cats/data/Func.scala b/core/src/main/scala/cats/data/Func.scala index 7081cc08fb..52e8190487 100644 --- a/core/src/main/scala/cats/data/Func.scala +++ b/core/src/main/scala/cats/data/Func.scala @@ -102,7 +102,9 @@ sealed private[data] trait FuncContravariant[F[_], C] extends Contravariant[λ[ Func.func(a => fa.run(f(a))) } -sealed private[data] trait FuncApply[F[_], C] extends Apply[λ[α => Func[F, C, α]]] with FuncFunctor[F, C] { +sealed private[data] trait FuncApply[F[_], C] + extends Apply.AbstractApply[λ[α => Func[F, C, α]]] + with FuncFunctor[F, C] { def F: Apply[F] def ap[A, B](f: Func[F, C, A => B])(fa: Func[F, C, A]): Func[F, C, B] = Func.func(c => F.ap(f.run(c))(fa.run(c))) @@ -110,7 +112,7 @@ sealed private[data] trait FuncApply[F[_], C] extends Apply[λ[α => Func[F, C, Func.func(c => F.product(fa.run(c), fb.run(c))) } -sealed private[data] trait FuncApplicative[F[_], C] extends Applicative[λ[α => Func[F, C, α]]] with FuncApply[F, C] { +sealed private[data] trait FuncApplicative[F[_], C] extends FuncApply[F, C] with Applicative[λ[α => Func[F, C, α]]] { def F: Applicative[F] def pure[A](a: A): Func[F, C, A] = Func.func(Function.const(F.pure(a))) @@ -158,7 +160,10 @@ abstract private[data] class AppFuncInstances { } } -sealed private[data] trait AppFuncApplicative[F[_], C] extends Applicative[λ[α => AppFunc[F, C, α]]] { +sealed abstract private[data] class AppFuncApplicative[F[_], C] + extends Apply.AbstractApply[λ[α => AppFunc[F, C, α]]] + with Applicative[λ[α => AppFunc[F, C, α]]] { + def F: Applicative[F] override def map[A, B](fa: AppFunc[F, C, A])(f: A => B): AppFunc[F, C, B] = fa.map(f) diff --git a/core/src/main/scala/cats/data/IdT.scala b/core/src/main/scala/cats/data/IdT.scala index 845ac008c7..cc862b5756 100644 --- a/core/src/main/scala/cats/data/IdT.scala +++ b/core/src/main/scala/cats/data/IdT.scala @@ -150,7 +150,7 @@ sealed private[data] trait IdTFunctor[F[_]] extends Functor[IdT[F, *]] { fa.map(f) } -sealed private[data] trait IdTApply[F[_]] extends Apply[IdT[F, *]] with IdTFunctor[F] { +sealed private[data] trait IdTApply[F[_]] extends Apply.AbstractApply[IdT[F, *]] with IdTFunctor[F] { implicit val F0: Apply[F] override def ap[A, B](ff: IdT[F, A => B])(fa: IdT[F, A]): IdT[F, B] = fa.ap(ff) @@ -160,7 +160,7 @@ sealed private[data] trait IdTApply[F[_]] extends Apply[IdT[F, *]] with IdTFunct .map(IdT(_)) } -sealed private[data] trait IdTApplicative[F[_]] extends Applicative[IdT[F, *]] with IdTApply[F] { +sealed private[data] trait IdTApplicative[F[_]] extends IdTApply[F] with Applicative[IdT[F, *]] { implicit val F0: Applicative[F] def pure[A](a: A): IdT[F, A] = IdT.pure(a) @@ -178,7 +178,7 @@ sealed private[data] trait IdTContravariantMonoidal[F[_]] extends ContravariantM IdT(F0.product(fa.value, fb.value)) } -sealed private[data] trait IdTFlatMap[F[_]] extends FlatMap[IdT[F, *]] with IdTApply[F] { +sealed private[data] trait IdTFlatMap[F[_]] extends FlatMap.AbstractFlatMap[IdT[F, *]] with IdTApply[F] { implicit val F0: FlatMap[F] def flatMap[A, B](fa: IdT[F, A])(f: A => IdT[F, B]): IdT[F, B] = @@ -188,11 +188,11 @@ sealed private[data] trait IdTFlatMap[F[_]] extends FlatMap[IdT[F, *]] with IdTA IdT(F0.tailRecM(a)(f(_).value)) } -sealed private[data] trait IdTMonad[F[_]] extends Monad[IdT[F, *]] with IdTApplicative[F] with IdTFlatMap[F] { +sealed private[data] trait IdTMonad[F[_]] extends IdTFlatMap[F] with IdTApplicative[F] with Monad[IdT[F, *]] { implicit val F0: Monad[F] } -sealed private[data] trait IdTFoldable[F[_]] extends Foldable[IdT[F, *]] { +sealed private[data] trait IdTFoldable[F[_]] extends Foldable.AbstractFoldable[IdT[F, *]] { implicit val F0: Foldable[F] def foldLeft[A, B](fa: IdT[F, A], b: B)(f: (B, A) => B): B = @@ -208,7 +208,7 @@ sealed private[data] trait IdTFoldable[F[_]] extends Foldable[IdT[F, *]] { F0.get(fa.value)(idx) } -sealed private[data] trait IdTTraverse[F[_]] extends Traverse[IdT[F, *]] with IdTFoldable[F] with IdTFunctor[F] { +sealed private[data] trait IdTTraverse[F[_]] extends IdTFoldable[F] with IdTFunctor[F] with Traverse[IdT[F, *]] { implicit val F0: Traverse[F] def traverse[G[_]: Applicative, A, B](fa: IdT[F, A])(f: A => G[B]): G[IdT[F, B]] = diff --git a/core/src/main/scala/cats/data/IndexedReaderWriterStateT.scala b/core/src/main/scala/cats/data/IndexedReaderWriterStateT.scala index b766600431..ca6bc53df0 100644 --- a/core/src/main/scala/cats/data/IndexedReaderWriterStateT.scala +++ b/core/src/main/scala/cats/data/IndexedReaderWriterStateT.scala @@ -698,7 +698,7 @@ sealed abstract private[data] class IRWSTInstances3 { } } -sealed abstract private[data] class IRWSTFunctor[F[_], E, L, SA, SB] +sealed private[data] trait IRWSTFunctor[F[_], E, L, SA, SB] extends Functor[IndexedReaderWriterStateT[F, E, L, SA, SB, *]] { implicit def F: Functor[F] @@ -759,7 +759,8 @@ sealed abstract private[data] class IRWSTBifunctor[F[_], E, L, SA] } sealed abstract private[data] class RWSTMonad[F[_], E, L, S] - extends IRWSTFunctor[F, E, L, S, S] + extends FlatMap.AbstractFlatMap[ReaderWriterStateT[F, E, L, S, *]] + with IRWSTFunctor[F, E, L, S, S] with Monad[ReaderWriterStateT[F, E, L, S, *]] { implicit def F: Monad[F] implicit def L: Monoid[L] @@ -790,8 +791,10 @@ sealed abstract private[data] class RWSTMonad[F[_], E, L, S] sealed abstract private[data] class IRWSTSemigroupK[F[_], E, L, SA, SB] extends IRWSTSemigroupK1[F, E, L, SA, SB] sealed abstract private[data] class RWSTAlternative[F[_], E, L, S] - extends IRWSTFunctor[F, E, L, S, S] - with RWSTAlternative1[F, E, L, S] + extends RWSTAlternative1[F, E, L, S] + with IRWSTFunctor[F, E, L, S, S] { + def F: Monad[F] +} sealed abstract private[data] class RWSTMonadError[F[_], E, L, S, R] extends RWSTMonad[F, E, L, S] @@ -822,7 +825,8 @@ private trait IRWSTSemigroupK1[F[_], E, L, SA, SB] extends SemigroupK[IndexedRea } private trait RWSTAlternative1[F[_], E, L, S] - extends IRWSTSemigroupK1[F, E, L, S, S] + extends Apply.AbstractApply[ReaderWriterStateT[F, E, L, S, *]] + with IRWSTSemigroupK1[F, E, L, S, S] with Alternative[ReaderWriterStateT[F, E, L, S, *]] { implicit def F: Monad[F] diff --git a/core/src/main/scala/cats/data/IndexedStateT.scala b/core/src/main/scala/cats/data/IndexedStateT.scala index 8cfec758a6..ead627a2c7 100644 --- a/core/src/main/scala/cats/data/IndexedStateT.scala +++ b/core/src/main/scala/cats/data/IndexedStateT.scala @@ -399,7 +399,7 @@ abstract private[data] class StateFunctions { def set[S](s: S): State[S, Unit] = State(_ => (s, ())) } -sealed abstract private[data] class IndexedStateTFunctor[F[_], SA, SB] extends Functor[IndexedStateT[F, SA, SB, *]] { +sealed private[data] trait IndexedStateTFunctor[F[_], SA, SB] extends Functor[IndexedStateT[F, SA, SB, *]] { implicit def F: Functor[F] override def map[A, B](fa: IndexedStateT[F, SA, SB, A])(f: A => B): IndexedStateT[F, SA, SB, B] = @@ -445,7 +445,8 @@ sealed abstract private[data] class IndexedStateTStrong[F[_], V] } sealed abstract private[data] class IndexedStateTMonad[F[_], S] - extends IndexedStateTFunctor[F, S, S] + extends FlatMap.AbstractFlatMap[IndexedStateT[F, S, S, *]] + with IndexedStateTFunctor[F, S, S] with Monad[IndexedStateT[F, S, S, *]] { implicit def F: Monad[F] diff --git a/core/src/main/scala/cats/data/Ior.scala b/core/src/main/scala/cats/data/Ior.scala index 78ed77d097..c577be33ec 100644 --- a/core/src/main/scala/cats/data/Ior.scala +++ b/core/src/main/scala/cats/data/Ior.scala @@ -865,7 +865,7 @@ sealed abstract private[data] class IorInstances extends IorInstances0 { implicit def catsDataSemigroupForIor[A: Semigroup, B: Semigroup]: Semigroup[Ior[A, B]] = _ combine _ implicit def catsDataMonadErrorForIor[A: Semigroup]: MonadError[Ior[A, *], A] = - new MonadError[Ior[A, *], A] { + new FlatMap.AbstractFlatMap[Ior[A, *]] with MonadError[Ior[A, *], A] { def raiseError[B](e: A): Ior[A, B] = Ior.left(e) @@ -921,7 +921,7 @@ sealed abstract private[data] class IorInstances extends IorInstances0 { def parallel: Ior[E, *] ~> Ior[E, *] = identityK def sequential: Ior[E, *] ~> Ior[E, *] = identityK - val applicative: Applicative[Ior[E, *]] = new Applicative[Ior[E, *]] { + val applicative: Applicative[Ior[E, *]] = new Apply.AbstractApply[Ior[E, *]] with Applicative[Ior[E, *]] { def pure[A](a: A): Ior[E, A] = Ior.right(a) def ap[A, B](ff: Ior[E, A => B])(fa: Ior[E, A]): Ior[E, B] = fa match { @@ -954,7 +954,7 @@ sealed abstract private[data] class IorInstances extends IorInstances0 { sealed abstract private[data] class IorInstances0 { implicit def catsDataTraverseFunctorForIor[A]: Traverse[Ior[A, *]] = - new Traverse[Ior[A, *]] { + new Foldable.AbstractFoldable[Ior[A, *]] with Traverse[Ior[A, *]] { def traverse[F[_]: Applicative, B, C](fa: A Ior B)(f: B => F[C]): F[A Ior C] = fa.traverse(f) diff --git a/core/src/main/scala/cats/data/IorT.scala b/core/src/main/scala/cats/data/IorT.scala index 4f2e1272ec..aa04b9f9dc 100644 --- a/core/src/main/scala/cats/data/IorT.scala +++ b/core/src/main/scala/cats/data/IorT.scala @@ -527,7 +527,8 @@ abstract private[data] class IorTInstances extends IorTInstances1 { private[this] val FA: Applicative[P.F] = P.applicative private[this] val IorA: Applicative[Ior[E, *]] = Parallel[Ior[E, *], Ior[E, *]].applicative - val applicative: Applicative[IorT[P.F, E, *]] = new Applicative[IorT[P.F, E, *]] { + val applicative: Applicative[IorT[P.F, E, *]] = new Apply.AbstractApply[IorT[P.F, E, *]] + with Applicative[IorT[P.F, E, *]] { def pure[A](a: A): IorT[P.F, E, A] = IorT.pure(a)(FA) def ap[A, B](ff: IorT[P.F, E, A => B])(fa: IorT[P.F, E, A]): IorT[P.F, E, B] = IorT(FA.map2(ff.value, fa.value)((f, a) => IorA.ap(f)(a))) @@ -560,7 +561,8 @@ abstract private[data] class IorTInstances extends IorTInstances1 { private[this] val IorA: Applicative[Ior[E, *]] = Ior.catsDataMonadErrorForIor // See https://github.com/typelevel/cats/issues/3783 - val applicative: Applicative[IorT[P.F, E, *]] = new Applicative[IorT[P.F, E, *]] { + val applicative: Applicative[IorT[P.F, E, *]] = new Apply.AbstractApply[IorT[P.F, E, *]] + with Applicative[IorT[P.F, E, *]] { def pure[A](a: A): IorT[P.F, E, A] = IorT.pure(a)(FA) def ap[A, B](ff: IorT[P.F, E, A => B])(fa: IorT[P.F, E, A]): IorT[P.F, E, B] = IorT(FA.map2(ff.value, fa.value)((f, a) => IorA.ap(f)(a))) @@ -605,7 +607,8 @@ abstract private[data] class IorTInstances1 extends IorTInstances2 { def parallel: IorT[F0, E, *] ~> IorT[F0, E, *] = identityK def sequential: IorT[F0, E, *] ~> IorT[F0, E, *] = identityK - val applicative: Applicative[IorT[F0, E, *]] = new Applicative[IorT[F0, E, *]] { + val applicative: Applicative[IorT[F0, E, *]] = new Apply.AbstractApply[IorT[F0, E, *]] + with Applicative[IorT[F0, E, *]] { def pure[A](a: A): IorT[F0, E, A] = IorT.pure(a) def ap[A, B](ff: IorT[F0, E, A => B])(fa: IorT[F0, E, A]): IorT[F0, E, B] = IorT(F.map2(ff.value, fa.value)((f, a) => underlyingParallel.applicative.ap[A, B](f)(a))) @@ -656,7 +659,10 @@ sealed private[data] trait IorTOrder[F[_], A, B] extends Order[IorT[F, A, B]] { override def compare(x: IorT[F, A, B], y: IorT[F, A, B]): Int = x.compare(y) } -sealed private[data] trait IorTMonad[F[_], A] extends Monad[IorT[F, A, *]] with IorTFunctor[F, A] { +sealed private[data] trait IorTMonad[F[_], A] + extends FlatMap.AbstractFlatMap[IorT[F, A, *]] + with Monad[IorT[F, A, *]] + with IorTFunctor[F, A] { implicit def A0: Semigroup[A] implicit override def F0: Monad[F] @@ -676,7 +682,7 @@ sealed private[data] trait IorTMonad[F[_], A] extends Monad[IorT[F, A, *]] with }) } -sealed private[data] trait IorTMonadError[F[_], A] extends MonadError[IorT[F, A, *], A] with IorTMonad[F, A] { +sealed private[data] trait IorTMonadError[F[_], A] extends IorTMonad[F, A] with MonadError[IorT[F, A, *], A] { override def raiseError[B](a: A): IorT[F, A, B] = IorT(F0.pure(Ior.left(a))) override def handleErrorWith[B](iort: IorT[F, A, B])(f: A => IorT[F, A, B]): IorT[F, A, B] = @@ -686,7 +692,7 @@ sealed private[data] trait IorTMonadError[F[_], A] extends MonadError[IorT[F, A, }) } -sealed private[data] trait IorTMonadErrorF[F[_], A, E] extends MonadError[IorT[F, A, *], E] with IorTMonad[F, A] { +sealed private[data] trait IorTMonadErrorF[F[_], A, E] extends IorTMonad[F, A] with MonadError[IorT[F, A, *], E] { implicit override def F0: MonadError[F, E] override def raiseError[B](e: E): IorT[F, A, B] = IorT(F0.raiseError(e)) @@ -708,7 +714,7 @@ sealed private[data] trait IorTMonoid[F[_], A, B] extends Monoid[IorT[F, A, B]] override def empty: IorT[F, A, B] = IorT(F0.empty) } -sealed private[data] trait IorTFoldable[F[_], A] extends Foldable[IorT[F, A, *]] { +sealed private[data] trait IorTFoldable[F[_], A] extends Foldable.AbstractFoldable[IorT[F, A, *]] { implicit def F0: Foldable[F] override def foldLeft[B, C](iort: IorT[F, A, B], c: C)(f: (C, B) => C): C = iort.foldLeft(c)(f) @@ -717,7 +723,7 @@ sealed private[data] trait IorTFoldable[F[_], A] extends Foldable[IorT[F, A, *]] iort.foldRight(lc)(f) } -sealed private[data] trait IorTTraverse[F[_], A] extends Traverse[IorT[F, A, *]] with IorTFoldable[F, A] { +sealed private[data] trait IorTTraverse[F[_], A] extends IorTFoldable[F, A] with Traverse[IorT[F, A, *]] { implicit override def F0: Traverse[F] override def traverse[G[_]: Applicative, B, D](iort: IorT[F, A, B])(f: B => G[D]): G[IorT[F, A, D]] = iort.traverse(f) diff --git a/core/src/main/scala/cats/data/Kleisli.scala b/core/src/main/scala/cats/data/Kleisli.scala index b62fc8ab34..6bba68ed6e 100644 --- a/core/src/main/scala/cats/data/Kleisli.scala +++ b/core/src/main/scala/cats/data/Kleisli.scala @@ -643,9 +643,9 @@ sealed private[data] trait KleisliMonoidK[F[_], A] extends MonoidK[Kleisli[F, A, } private[data] trait KleisliAlternative[F[_], A] - extends Alternative[Kleisli[F, A, *]] - with KleisliApplicative[F, A] - with KleisliMonoidK[F, A] { + extends KleisliApplicative[F, A] + with KleisliMonoidK[F, A] + with Alternative[Kleisli[F, A, *]] { implicit def F: Alternative[F] } @@ -662,15 +662,15 @@ sealed private[data] trait KleisliContravariantMonoidal[F[_], D] extends Contrav } private[data] trait KleisliMonadError[F[_], A, E] - extends MonadError[Kleisli[F, A, *], E] + extends KleisliMonad[F, A] with KleisliApplicativeError[F, A, E] - with KleisliMonad[F, A] { + with MonadError[Kleisli[F, A, *], E] { def F: MonadError[F, E] } private[data] trait KleisliApplicativeError[F[_], A, E] - extends ApplicativeError[Kleisli[F, A, *], E] - with KleisliApplicative[F, A] { + extends KleisliApplicative[F, A] + with ApplicativeError[Kleisli[F, A, *], E] { type K[T] = Kleisli[F, A, T] implicit def F: ApplicativeError[F, E] @@ -684,13 +684,13 @@ private[data] trait KleisliApplicativeError[F[_], A, E] } private[data] trait KleisliMonad[F[_], A] - extends Monad[Kleisli[F, A, *]] - with KleisliFlatMap[F, A] - with KleisliApplicative[F, A] { + extends KleisliFlatMap[F, A] + with KleisliApplicative[F, A] + with Monad[Kleisli[F, A, *]] { implicit def F: Monad[F] } -private[data] trait KleisliFlatMap[F[_], A] extends FlatMap[Kleisli[F, A, *]] with KleisliApply[F, A] { +private[data] trait KleisliFlatMap[F[_], A] extends FlatMap.AbstractFlatMap[Kleisli[F, A, *]] with KleisliApply[F, A] { implicit def F: FlatMap[F] def flatMap[B, C](fa: Kleisli[F, A, B])(f: B => Kleisli[F, A, C]): Kleisli[F, A, C] = @@ -702,14 +702,14 @@ private[data] trait KleisliFlatMap[F[_], A] extends FlatMap[Kleisli[F, A, *]] wi } } -private[data] trait KleisliApplicative[F[_], A] extends Applicative[Kleisli[F, A, *]] with KleisliApply[F, A] { +private[data] trait KleisliApplicative[F[_], A] extends KleisliApply[F, A] with Applicative[Kleisli[F, A, *]] { implicit def F: Applicative[F] def pure[B](x: B): Kleisli[F, A, B] = Kleisli.pure[F, A, B](x) } -private[data] trait KleisliApply[F[_], A] extends Apply[Kleisli[F, A, *]] with KleisliFunctor[F, A] { +private[data] trait KleisliApply[F[_], A] extends Apply.AbstractApply[Kleisli[F, A, *]] with KleisliFunctor[F, A] { implicit def F: Apply[F] override def ap[B, C](f: Kleisli[F, A, B => C])(fa: Kleisli[F, A, B]): Kleisli[F, A, C] = diff --git a/core/src/main/scala/cats/data/Nested.scala b/core/src/main/scala/cats/data/Nested.scala index 70569287f7..24f6aafe6d 100644 --- a/core/src/main/scala/cats/data/Nested.scala +++ b/core/src/main/scala/cats/data/Nested.scala @@ -279,7 +279,7 @@ private[data] trait NestedFunctor[F[_], G[_]] extends Functor[Nested[F, G, *]] w Nested(FG.map(fga.value)(f)) } -private[data] trait NestedApply[F[_], G[_]] extends Apply[Nested[F, G, *]] with NestedFunctor[F, G] { +private[data] trait NestedApply[F[_], G[_]] extends Apply.AbstractApply[Nested[F, G, *]] with NestedFunctor[F, G] { override def FG: Apply[λ[α => F[G[α]]]] override def ap[A, B](fgf: Nested[F, G, A => B])(fga: Nested[F, G, A]): Nested[F, G, B] = @@ -289,15 +289,15 @@ private[data] trait NestedApply[F[_], G[_]] extends Apply[Nested[F, G, *]] with Nested(FG.product(fga.value, fgb.value)) } -private[data] trait NestedApplicative[F[_], G[_]] extends Applicative[Nested[F, G, *]] with NestedApply[F, G] { +private[data] trait NestedApplicative[F[_], G[_]] extends NestedApply[F, G] with Applicative[Nested[F, G, *]] { def FG: Applicative[λ[α => F[G[α]]]] def pure[A](x: A): Nested[F, G, A] = Nested(FG.pure(x)) } abstract private[data] class NestedApplicativeError[F[_], G[_], E] - extends ApplicativeError[Nested[F, G, *], E] - with NestedApplicative[F, G] { + extends NestedApplicative[F, G] + with ApplicativeError[Nested[F, G, *], E] { def G: Applicative[G] def AEF: ApplicativeError[F, E] @@ -323,13 +323,13 @@ private[data] trait NestedMonoidK[F[_], G[_]] extends MonoidK[Nested[F, G, *]] w } private[data] trait NestedAlternative[F[_], G[_]] - extends Alternative[Nested[F, G, *]] - with NestedApplicative[F, G] - with NestedMonoidK[F, G] { + extends NestedApplicative[F, G] + with NestedMonoidK[F, G] + with Alternative[Nested[F, G, *]] { def FG: Alternative[λ[α => F[G[α]]]] } -private[data] trait NestedFoldable[F[_], G[_]] extends Foldable[Nested[F, G, *]] { +private[data] trait NestedFoldable[F[_], G[_]] extends Foldable.AbstractFoldable[Nested[F, G, *]] { def FG: Foldable[λ[α => F[G[α]]]] def foldLeft[A, B](fga: Nested[F, G, A], b: B)(f: (B, A) => B): B = @@ -340,9 +340,9 @@ private[data] trait NestedFoldable[F[_], G[_]] extends Foldable[Nested[F, G, *]] } private[data] trait NestedTraverse[F[_], G[_]] - extends Traverse[Nested[F, G, *]] - with NestedFoldable[F, G] - with NestedFunctor[F, G] { + extends NestedFoldable[F, G] + with NestedFunctor[F, G] + with Traverse[Nested[F, G, *]] { def FG: Traverse[λ[α => F[G[α]]]] override def traverse[H[_]: Applicative, A, B](fga: Nested[F, G, A])(f: A => H[B]): H[Nested[F, G, B]] = @@ -367,7 +367,7 @@ private[data] trait NestedDistributive[F[_], G[_]] extends Distributive[Nested[F }) } -private[data] trait NestedReducible[F[_], G[_]] extends Reducible[Nested[F, G, *]] with NestedFoldable[F, G] { +private[data] trait NestedReducible[F[_], G[_]] extends NestedFoldable[F, G] with Reducible[Nested[F, G, *]] { def FG: Reducible[λ[α => F[G[α]]]] def reduceLeftTo[A, B](fga: Nested[F, G, A])(f: A => B)(g: (B, A) => B): B = @@ -378,8 +378,8 @@ private[data] trait NestedReducible[F[_], G[_]] extends Reducible[Nested[F, G, * } private[data] trait NestedNonEmptyTraverse[F[_], G[_]] - extends NonEmptyTraverse[Nested[F, G, *]] - with NestedTraverse[F, G] + extends NestedTraverse[F, G] + with NonEmptyTraverse[Nested[F, G, *]] with NestedReducible[F, G] { def FG: NonEmptyTraverse[λ[α => F[G[α]]]] diff --git a/core/src/main/scala/cats/data/NonEmptyChain.scala b/core/src/main/scala/cats/data/NonEmptyChain.scala index 6a01639211..aca64f565e 100644 --- a/core/src/main/scala/cats/data/NonEmptyChain.scala +++ b/core/src/main/scala/cats/data/NonEmptyChain.scala @@ -637,6 +637,8 @@ sealed abstract private[data] class NonEmptyChainInstances extends NonEmptyChain new AbstractNonEmptyInstances[Chain, NonEmptyChain] with Align[NonEmptyChain] { def extract[A](fa: NonEmptyChain[A]): A = fa.head + override def split[A](fa: NonEmptyChain[A]): (A, Chain[A]) = (fa.head, fa.tail) + def nonEmptyTraverse[G[_]: Apply, A, B](fa: NonEmptyChain[A])(f: A => G[B]): G[NonEmptyChain[B]] = { def loop(head: A, tail: Chain[A]): Eval[G[NonEmptyChain[B]]] = tail.uncons.fold(Eval.now(Apply[G].map(f(head))(NonEmptyChain(_)))) { case (h, t) => @@ -666,9 +668,11 @@ sealed abstract private[data] class NonEmptyChainInstances extends NonEmptyChain override def reduce[A](fa: NonEmptyChain[A])(implicit A: Semigroup[A]): A = fa.reduce - def reduceLeftTo[A, B](fa: NonEmptyChain[A])(f: A => B)(g: (B, A) => B): B = fa.reduceLeftTo(f)(g) + override def reduceLeftTo[A, B](fa: NonEmptyChain[A])(f: A => B)(g: (B, A) => B): B = fa.reduceLeftTo(f)(g) - def reduceRightTo[A, B](fa: NonEmptyChain[A])(f: A => B)(g: (A, cats.Eval[B]) => cats.Eval[B]): cats.Eval[B] = + override def reduceRightTo[A, B]( + fa: NonEmptyChain[A] + )(f: A => B)(g: (A, cats.Eval[B]) => cats.Eval[B]): cats.Eval[B] = Eval.defer(fa.reduceRightTo(a => Eval.later(f(a))) { (a, b) => Eval.defer(g(a, b)) }) diff --git a/core/src/main/scala/cats/data/NonEmptyList.scala b/core/src/main/scala/cats/data/NonEmptyList.scala index c5133d96b8..1006af2f3f 100644 --- a/core/src/main/scala/cats/data/NonEmptyList.scala +++ b/core/src/main/scala/cats/data/NonEmptyList.scala @@ -777,7 +777,7 @@ object NonEmptyList extends NonEmptyListInstances { new ZipNonEmptyList(nev) implicit val catsDataCommutativeApplyForZipNonEmptyList: CommutativeApply[ZipNonEmptyList] = - new CommutativeApply[ZipNonEmptyList] { + new Apply.AbstractApply[ZipNonEmptyList] with CommutativeApply[ZipNonEmptyList] { def ap[A, B](ff: ZipNonEmptyList[A => B])(fa: ZipNonEmptyList[A]): ZipNonEmptyList[B] = ZipNonEmptyList(ff.value.zipWith(fa.value)(_.apply(_))) @@ -815,12 +815,16 @@ sealed abstract private[data] class NonEmptyListInstances extends NonEmptyListIn : NonEmptyAlternative[NonEmptyList] & Bimonad[NonEmptyList] & NonEmptyTraverse[NonEmptyList] & Align[ NonEmptyList ] = - new NonEmptyReducible[NonEmptyList, List] + new FlatMap.FoldableFlatMap[NonEmptyList] + with NonEmptyReducibleTrait[NonEmptyList, List] with NonEmptyAlternative[NonEmptyList] with Bimonad[NonEmptyList] with NonEmptyTraverse[NonEmptyList] with Align[NonEmptyList] { + override def G: Foldable[List] = + cats.instances.list.catsStdInstancesForList + def combineK[A](a: NonEmptyList[A], b: NonEmptyList[A]): NonEmptyList[A] = a.concatNel(b) diff --git a/core/src/main/scala/cats/data/NonEmptyMapImpl.scala b/core/src/main/scala/cats/data/NonEmptyMapImpl.scala index 373f59f6a2..dee786abc8 100644 --- a/core/src/main/scala/cats/data/NonEmptyMapImpl.scala +++ b/core/src/main/scala/cats/data/NonEmptyMapImpl.scala @@ -297,7 +297,10 @@ sealed abstract private[data] class NonEmptyMapInstances extends NonEmptyMapInst implicit def catsDataInstancesForNonEmptyMap[K] : SemigroupK[NonEmptyMap[K, *]] & NonEmptyTraverse[NonEmptyMap[K, *]] & Align[NonEmptyMap[K, *]] = - new SemigroupK[NonEmptyMap[K, *]] with NonEmptyTraverse[NonEmptyMap[K, *]] with Align[NonEmptyMap[K, *]] { + new Foldable.AbstractFoldable[NonEmptyMap[K, *]] + with SemigroupK[NonEmptyMap[K, *]] + with NonEmptyTraverse[NonEmptyMap[K, *]] + with Align[NonEmptyMap[K, *]] { override def map[A, B](fa: NonEmptyMap[K, A])(f: A => B): NonEmptyMap[K, B] = fa.map(f) diff --git a/core/src/main/scala/cats/data/NonEmptySeq.scala b/core/src/main/scala/cats/data/NonEmptySeq.scala index c563feeb7c..46f6a92bc5 100644 --- a/core/src/main/scala/cats/data/NonEmptySeq.scala +++ b/core/src/main/scala/cats/data/NonEmptySeq.scala @@ -417,12 +417,16 @@ sealed abstract private[data] class NonEmptySeqInstances { */ implicit val catsDataInstancesForNonEmptySeqBinCompat1 : NonEmptyAlternative[NonEmptySeq] & Bimonad[NonEmptySeq] & NonEmptyTraverse[NonEmptySeq] & Align[NonEmptySeq] = - new NonEmptyReducible[NonEmptySeq, Seq] + new FlatMap.FoldableFlatMap[NonEmptySeq] + with NonEmptyReducibleTrait[NonEmptySeq, Seq] with NonEmptyAlternative[NonEmptySeq] with Bimonad[NonEmptySeq] with NonEmptyTraverse[NonEmptySeq] with Align[NonEmptySeq] { + override def G: Foldable[Seq] = + cats.instances.seq.catsStdInstancesForSeq + def combineK[A](a: NonEmptySeq[A], b: NonEmptySeq[A]): NonEmptySeq[A] = a.concatNeSeq(b) @@ -617,7 +621,7 @@ object NonEmptySeq extends NonEmptySeqInstances with Serializable { new ZipNonEmptySeq(nev) implicit val catsDataCommutativeApplyForZipNonEmptySeq: CommutativeApply[ZipNonEmptySeq] = - new CommutativeApply[ZipNonEmptySeq] { + new Apply.AbstractApply[ZipNonEmptySeq] with CommutativeApply[ZipNonEmptySeq] { def ap[A, B](ff: ZipNonEmptySeq[A => B])(fa: ZipNonEmptySeq[A]): ZipNonEmptySeq[B] = ZipNonEmptySeq(ff.value.zipWith(fa.value)(_.apply(_))) diff --git a/core/src/main/scala/cats/data/NonEmptyVector.scala b/core/src/main/scala/cats/data/NonEmptyVector.scala index 554fadd882..90288eab44 100644 --- a/core/src/main/scala/cats/data/NonEmptyVector.scala +++ b/core/src/main/scala/cats/data/NonEmptyVector.scala @@ -410,12 +410,16 @@ sealed abstract private[data] class NonEmptyVectorInstances extends NonEmptyVect : NonEmptyAlternative[NonEmptyVector] & Bimonad[NonEmptyVector] & NonEmptyTraverse[NonEmptyVector] & Align[ NonEmptyVector ] = - new NonEmptyReducible[NonEmptyVector, Vector] + new FlatMap.FoldableFlatMap[NonEmptyVector] + with NonEmptyReducibleTrait[NonEmptyVector, Vector] with NonEmptyAlternative[NonEmptyVector] with Bimonad[NonEmptyVector] with NonEmptyTraverse[NonEmptyVector] with Align[NonEmptyVector] { + override def G: Foldable[Vector] = + cats.instances.vector.catsStdInstancesForVector + def combineK[A](a: NonEmptyVector[A], b: NonEmptyVector[A]): NonEmptyVector[A] = a.concatNev(b) @@ -625,7 +629,7 @@ object NonEmptyVector extends NonEmptyVectorInstances with Serializable { new ZipNonEmptyVector(nev) implicit val catsDataCommutativeApplyForZipNonEmptyVector: CommutativeApply[ZipNonEmptyVector] = - new CommutativeApply[ZipNonEmptyVector] { + new Apply.AbstractApply[ZipNonEmptyVector] with CommutativeApply[ZipNonEmptyVector] { def ap[A, B](ff: ZipNonEmptyVector[A => B])(fa: ZipNonEmptyVector[A]): ZipNonEmptyVector[B] = ZipNonEmptyVector(ff.value.zipWith(fa.value)(_.apply(_))) diff --git a/core/src/main/scala/cats/data/OneAnd.scala b/core/src/main/scala/cats/data/OneAnd.scala index 06df7e742b..e56a563ae3 100644 --- a/core/src/main/scala/cats/data/OneAnd.scala +++ b/core/src/main/scala/cats/data/OneAnd.scala @@ -171,7 +171,7 @@ sealed abstract private[data] class OneAndInstances extends OneAndLowPriority0 { monad: Monad[F], alternative: Alternative[F] ): Monad[OneAnd[F, *]] = - new Monad[OneAnd[F, *]] { + new FlatMap.AbstractFlatMap[OneAnd[F, *]] with Monad[OneAnd[F, *]] { override def map[A, B](fa: OneAnd[F, A])(f: A => B): OneAnd[F, B] = fa.map(f)(monad) @@ -236,7 +236,7 @@ sealed abstract private[data] class OneAndLowPriority3 extends OneAndLowPriority sealed abstract private[data] class OneAndLowPriority2 extends OneAndLowPriority3 { implicit def catsDataApplicativeForOneAnd[F[_]](implicit F: Alternative[F]): Applicative[OneAnd[F, *]] = - new Applicative[OneAnd[F, *]] { + new Apply.AbstractApply[OneAnd[F, *]] with Applicative[OneAnd[F, *]] { override def map[A, B](fa: OneAnd[F, A])(f: A => B): OneAnd[F, B] = fa.map(f) diff --git a/core/src/main/scala/cats/data/OptionT.scala b/core/src/main/scala/cats/data/OptionT.scala index e900783d60..c7e57b5829 100644 --- a/core/src/main/scala/cats/data/OptionT.scala +++ b/core/src/main/scala/cats/data/OptionT.scala @@ -954,7 +954,7 @@ sealed private[data] trait OptionTContravariant[F[_]] extends Contravariant[Opti fa.contramap(f) } -private[data] trait OptionTMonad[F[_]] extends Monad[OptionT[F, *]] { +private[data] trait OptionTMonad[F[_]] extends FlatMap.AbstractFlatMap[OptionT[F, *]] with Monad[OptionT[F, *]] { implicit def F: Monad[F] def pure[A](a: A): OptionT[F, A] = OptionT.pure(a) @@ -973,7 +973,7 @@ private[data] trait OptionTMonad[F[_]] extends Monad[OptionT[F, *]] { ) } -private[data] trait OptionTMonadErrorMonad[F[_]] extends MonadError[OptionT[F, *], Unit] with OptionTMonad[F] { +private[data] trait OptionTMonadErrorMonad[F[_]] extends OptionTMonad[F] with MonadError[OptionT[F, *], Unit] { implicit def F: Monad[F] override def raiseError[A](e: Unit): OptionT[F, A] = OptionT.none @@ -985,7 +985,7 @@ private[data] trait OptionTMonadErrorMonad[F[_]] extends MonadError[OptionT[F, * }) } -private trait OptionTMonadError[F[_], E] extends MonadError[OptionT[F, *], E] with OptionTMonad[F] { +private trait OptionTMonadError[F[_], E] extends OptionTMonad[F] with MonadError[OptionT[F, *], E] { override def F: MonadError[F, E] override def raiseError[A](e: E): OptionT[F, A] = @@ -1014,7 +1014,7 @@ private trait OptionTContravariantMonoidal[F[_]] extends ContravariantMonoidal[O ) } -private[data] trait OptionTFoldable[F[_]] extends Foldable[OptionT[F, *]] { +private[data] trait OptionTFoldable[F[_]] extends Foldable.AbstractFoldable[OptionT[F, *]] { implicit def F: Foldable[F] def foldLeft[A, B](fa: OptionT[F, A], b: B)(f: (B, A) => B): B = @@ -1024,7 +1024,7 @@ private[data] trait OptionTFoldable[F[_]] extends Foldable[OptionT[F, *]] { fa.foldRight(lb)(f) } -sealed private[data] trait OptionTTraverse[F[_]] extends Traverse[OptionT[F, *]] with OptionTFoldable[F] { +sealed private[data] trait OptionTTraverse[F[_]] extends OptionTFoldable[F] with Traverse[OptionT[F, *]] { implicit def F: Traverse[F] def traverse[G[_]: Applicative, A, B](fa: OptionT[F, A])(f: A => G[B]): G[OptionT[F, B]] = diff --git a/core/src/main/scala/cats/data/RepresentableStoreT.scala b/core/src/main/scala/cats/data/RepresentableStoreT.scala index 5cd2832da6..a0430c7e2c 100644 --- a/core/src/main/scala/cats/data/RepresentableStoreT.scala +++ b/core/src/main/scala/cats/data/RepresentableStoreT.scala @@ -21,7 +21,7 @@ package cats.data -import cats.{Applicative, Comonad, Functor, Monoid, Representable} +import cats.{Applicative, Apply, Comonad, Functor, Monoid, Representable} /* * The dual of `StateT`. Stores some state `A` indexed by @@ -130,7 +130,7 @@ trait RepresentableStoreTInstances1 extends RepresentableStoreTInstances2 { F: Representable.Aux[F, S], S: Monoid[S] ): Applicative[RepresentableStoreT[W, F, S, *]] = - new Applicative[RepresentableStoreT[W, F, S, *]] { + new Apply.AbstractApply[RepresentableStoreT[W, F, S, *]] with Applicative[RepresentableStoreT[W, F, S, *]] { def pure[A](x: A): RepresentableStoreT[W, F, S, A] = RepresentableStoreT.pure[W, F, S, A](x) diff --git a/core/src/main/scala/cats/data/Tuple2K.scala b/core/src/main/scala/cats/data/Tuple2K.scala index b5a1d88f4a..832a88dd09 100644 --- a/core/src/main/scala/cats/data/Tuple2K.scala +++ b/core/src/main/scala/cats/data/Tuple2K.scala @@ -310,7 +310,7 @@ sealed private[data] trait Tuple2KContravariantMonoidal[F[_], G[_]] } sealed private[data] trait Tuple2KApply[F[_], G[_]] - extends Apply[λ[α => Tuple2K[F, G, α]]] + extends Apply.AbstractApply[λ[α => Tuple2K[F, G, α]]] with Tuple2KFunctor[F, G] with Tuple2KSemigroupal[F, G] { def F: Apply[F] @@ -329,8 +329,8 @@ sealed private[data] trait Tuple2KApply[F[_], G[_]] } sealed private[data] trait Tuple2KApplicative[F[_], G[_]] - extends Applicative[λ[α => Tuple2K[F, G, α]]] - with Tuple2KApply[F, G] { + extends Tuple2KApply[F, G] + with Applicative[λ[α => Tuple2K[F, G, α]]] { def F: Applicative[F] def G: Applicative[G] def pure[A](a: A): Tuple2K[F, G, A] = Tuple2K(F.pure(a), G.pure(a)) @@ -353,16 +353,17 @@ sealed private[data] trait Tuple2KMonoidK[F[_], G[_]] } sealed private[data] trait Tuple2KAlternative[F[_], G[_]] - extends Alternative[λ[α => Tuple2K[F, G, α]]] - with Tuple2KApplicative[F, G] - with Tuple2KMonoidK[F, G] { + extends Tuple2KApplicative[F, G] + with Tuple2KMonoidK[F, G] + with Alternative[λ[α => Tuple2K[F, G, α]]] { def F: Alternative[F] def G: Alternative[G] } sealed private[data] trait Tuple2KMonad[F[_], G[_]] - extends Monad[λ[α => Tuple2K[F, G, α]]] - with Tuple2KApplicative[F, G] { + extends FlatMap.AbstractFlatMap[λ[α => Tuple2K[F, G, α]]] + with Tuple2KApplicative[F, G] + with Monad[λ[α => Tuple2K[F, G, α]]] { def F: Monad[F] def G: Monad[G] override def pure[A](a: A): Tuple2K[F, G, A] = @@ -375,7 +376,7 @@ sealed private[data] trait Tuple2KMonad[F[_], G[_]] Tuple2K(F.tailRecM(a)(f(_).first), G.tailRecM(a)(f(_).second)) } -sealed private[data] trait Tuple2KFoldable[F[_], G[_]] extends Foldable[λ[α => Tuple2K[F, G, α]]] { +sealed private[data] trait Tuple2KFoldable[F[_], G[_]] extends Foldable.AbstractFoldable[λ[α => Tuple2K[F, G, α]]] { def F: Foldable[F] def G: Foldable[G] @@ -387,8 +388,8 @@ sealed private[data] trait Tuple2KFoldable[F[_], G[_]] extends Foldable[λ[α => } sealed private[data] trait Tuple2KTraverse[F[_], G[_]] - extends Traverse[λ[α => Tuple2K[F, G, α]]] - with Tuple2KFoldable[F, G] { + extends Tuple2KFoldable[F, G] + with Traverse[λ[α => Tuple2K[F, G, α]]] { def F: Traverse[F] def G: Traverse[G] diff --git a/core/src/main/scala/cats/data/Validated.scala b/core/src/main/scala/cats/data/Validated.scala index a89d6e7607..459bb8d601 100644 --- a/core/src/main/scala/cats/data/Validated.scala +++ b/core/src/main/scala/cats/data/Validated.scala @@ -991,7 +991,7 @@ sealed abstract private[data] class ValidatedInstances2 { implicit def catsDataEqForValidated[A: Eq, B: Eq]: Eq[Validated[A, B]] = _ === _ implicit def catsDataTraverseFunctorForValidated[E]: Traverse[Validated[E, *]] = - new Traverse[Validated[E, *]] { + new Foldable.AbstractFoldable[Validated[E, *]] with Traverse[Validated[E, *]] { override def traverse[G[_]: Applicative, A, B](fa: Validated[E, A])(f: (A) => G[B]): G[Validated[E, B]] = fa.traverse(f) @@ -1060,7 +1060,10 @@ sealed abstract private[data] class ValidatedInstances2 { } } -private[data] class ValidatedApplicative[E: Semigroup] extends CommutativeApplicative[Validated[E, *]] { +private[data] class ValidatedApplicative[E: Semigroup] + extends Apply.AbstractApply[Validated[E, *]] + with CommutativeApplicative[Validated[E, *]] { + override def map[A, B](fa: Validated[E, A])(f: A => B): Validated[E, B] = fa.map(f) diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index c9acca8505..8a6279a2d5 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -614,7 +614,9 @@ sealed private[data] trait WriterTInvariant[F[_], L] extends Invariant[WriterT[F fa.imap(f)(g) } -sealed private[data] trait WriterTApply[F[_], L] extends WriterTFunctor[F, L] with Apply[WriterT[F, L, *]] { +sealed private[data] trait WriterTApply[F[_], L] + extends Apply.AbstractApply[WriterT[F, L, *]] + with WriterTFunctor[F, L] { implicit override def F0: Apply[F] implicit def L0: Semigroup[L] @@ -631,7 +633,9 @@ sealed private[data] trait WriterTApply[F[_], L] extends WriterTFunctor[F, L] wi WriterT(F0.map(F0.product(fa.run, fb.run)) { case ((l1, a), (l2, b)) => (L0.combine(l1, l2), (a, b)) }) } -sealed private[data] trait WriterTFlatMap1[F[_], L] extends WriterTApply[F, L] with FlatMap[WriterT[F, L, *]] { +sealed private[data] trait WriterTFlatMap1[F[_], L] + extends FlatMap.AbstractFlatMap[WriterT[F, L, *]] + with WriterTApply[F, L] { implicit override def F0: FlatMap[F] implicit def L0: Monoid[L] @@ -659,10 +663,15 @@ sealed private[data] trait WriterTFlatMap1[F[_], L] extends WriterTApply[F, L] w } } -sealed private[data] trait WriterTFlatMap2[F[_], L] extends WriterTApply[F, L] with FlatMap[WriterT[F, L, *]] { +sealed private[data] trait WriterTFlatMap2[F[_], L] + extends FlatMap.AbstractFlatMap[WriterT[F, L, *]] + with WriterTApply[F, L] { implicit override def F0: Monad[F] implicit def L0: Semigroup[L] + override def ap[A, B](f: WriterT[F, L, A => B])(fa: WriterT[F, L, A]) = + super[WriterTApply].ap(f)(fa) + def flatMap[A, B](fa: WriterT[F, L, A])(f: A => WriterT[F, L, B]): WriterT[F, L, B] = fa.flatMap(f) @@ -698,16 +707,16 @@ sealed private[data] trait WriterTApplicative[F[_], L] extends WriterTApply[F, L } sealed private[data] trait WriterTMonad[F[_], L] - extends WriterTApplicative[F, L] - with WriterTFlatMap1[F, L] + extends WriterTFlatMap1[F, L] + with WriterTApplicative[F, L] with Monad[WriterT[F, L, *]] { implicit override def F0: Monad[F] implicit override def L0: Monoid[L] } sealed private[data] trait WriterTApplicativeError[F[_], L, E] - extends ApplicativeError[WriterT[F, L, *], E] - with WriterTApplicative[F, L] { + extends WriterTApplicative[F, L] + with ApplicativeError[WriterT[F, L, *], E] { implicit override def F0: ApplicativeError[F, E] def raiseError[A](e: E): WriterT[F, L, A] = WriterT(F0.raiseError[(L, A)](e)) @@ -717,9 +726,9 @@ sealed private[data] trait WriterTApplicativeError[F[_], L, E] } sealed private[data] trait WriterTMonadError[F[_], L, E] - extends MonadError[WriterT[F, L, *], E] - with WriterTMonad[F, L] - with WriterTApplicativeError[F, L, E] { + extends WriterTMonad[F, L] + with WriterTApplicativeError[F, L, E] + with MonadError[WriterT[F, L, *], E] { implicit override def F0: MonadError[F, E] } @@ -740,9 +749,9 @@ sealed private[data] trait WriterTMonoidK[F[_], L] extends MonoidK[WriterT[F, L, } sealed private[data] trait WriterTAlternative[F[_], L] - extends Alternative[WriterT[F, L, *]] + extends WriterTApplicative[F, L] with WriterTMonoidK[F, L] - with WriterTApplicative[F, L] { + with Alternative[WriterT[F, L, *]] { implicit override def F0: Alternative[F] } @@ -782,7 +791,7 @@ sealed private[data] trait WriterTCoflatMap[F[_], L] extends CoflatMap[WriterT[F def coflatMap[A, B](fa: WriterT[F, L, A])(f: WriterT[F, L, A] => B): WriterT[F, L, B] = fa.map(_ => f(fa)) } -sealed private[data] trait WriterTFoldable[F[_], L] extends Foldable[WriterT[F, L, *]] { +sealed private[data] trait WriterTFoldable[F[_], L] extends Foldable.AbstractFoldable[WriterT[F, L, *]] { implicit def F0: Foldable[F] @@ -791,9 +800,9 @@ sealed private[data] trait WriterTFoldable[F[_], L] extends Foldable[WriterT[F, } sealed private[data] trait WriterTTraverse[F[_], L] - extends Traverse[WriterT[F, L, *]] - with WriterTFoldable[F, L] - with WriterTFunctor[F, L] { + extends WriterTFoldable[F, L] + with WriterTFunctor[F, L] + with Traverse[WriterT[F, L, *]] { implicit override def F0: Traverse[F] diff --git a/core/src/main/scala/cats/data/ZipList.scala b/core/src/main/scala/cats/data/ZipList.scala index 16439d58c4..a61c895b2a 100644 --- a/core/src/main/scala/cats/data/ZipList.scala +++ b/core/src/main/scala/cats/data/ZipList.scala @@ -31,7 +31,8 @@ object ZipList { def apply[A](value: List[A]): ZipList[A] = new ZipList(value) - implicit val catsDataCommutativeApplyForZipList: CommutativeApply[ZipList] = new CommutativeApply[ZipList] { + implicit val catsDataCommutativeApplyForZipList: CommutativeApply[ZipList] = new Apply.AbstractApply[ZipList] + with CommutativeApply[ZipList] { override def map[A, B](fa: ZipList[A])(f: (A) => B): ZipList[B] = ZipList(fa.value.map(f)) diff --git a/core/src/main/scala/cats/data/ZipSeq.scala b/core/src/main/scala/cats/data/ZipSeq.scala index 2b62718523..150dd0cbdd 100644 --- a/core/src/main/scala/cats/data/ZipSeq.scala +++ b/core/src/main/scala/cats/data/ZipSeq.scala @@ -32,7 +32,8 @@ object ZipSeq { def apply[A](value: Seq[A]): ZipSeq[A] = new ZipSeq(value) - implicit val catsDataCommutativeApplyForZipSeq: CommutativeApply[ZipSeq] = new CommutativeApply[ZipSeq] { + implicit val catsDataCommutativeApplyForZipSeq: CommutativeApply[ZipSeq] = new Apply.AbstractApply[ZipSeq] + with CommutativeApply[ZipSeq] { override def map[A, B](fa: ZipSeq[A])(f: (A) => B): ZipSeq[B] = ZipSeq(fa.value.map(f)) diff --git a/core/src/main/scala/cats/data/ZipVector.scala b/core/src/main/scala/cats/data/ZipVector.scala index 5048518d26..90a1345124 100644 --- a/core/src/main/scala/cats/data/ZipVector.scala +++ b/core/src/main/scala/cats/data/ZipVector.scala @@ -31,7 +31,8 @@ object ZipVector { def apply[A](value: Vector[A]): ZipVector[A] = new ZipVector(value) - implicit val catsDataCommutativeApplyForZipVector: CommutativeApply[ZipVector] = new CommutativeApply[ZipVector] { + implicit val catsDataCommutativeApplyForZipVector: CommutativeApply[ZipVector] = new Apply.AbstractApply[ZipVector] + with CommutativeApply[ZipVector] { override def map[A, B](fa: ZipVector[A])(f: (A) => B): ZipVector[B] = ZipVector(fa.value.map(f)) diff --git a/core/src/main/scala/cats/implicits.scala b/core/src/main/scala/cats/implicits.scala index 9404eda7b4..6f63778d33 100644 --- a/core/src/main/scala/cats/implicits.scala +++ b/core/src/main/scala/cats/implicits.scala @@ -22,7 +22,8 @@ package cats object implicits - extends syntax.AllSyntax + extends instances.AbstractAllInstances + with syntax.AllSyntax with syntax.AllSyntaxBinCompat0 with syntax.AllSyntaxBinCompat1 with syntax.AllSyntaxBinCompat2 @@ -30,7 +31,6 @@ object implicits with syntax.AllSyntaxBinCompat4 with syntax.AllSyntaxBinCompat5 with syntax.AllSyntaxBinCompat6 - with instances.AllInstances with instances.AllInstancesBinCompat0 with instances.AllInstancesBinCompat1 with instances.AllInstancesBinCompat2 diff --git a/core/src/main/scala/cats/instances/anyval.scala b/core/src/main/scala/cats/instances/anyval.scala index aea51929a0..7b3176eb51 100644 --- a/core/src/main/scala/cats/instances/anyval.scala +++ b/core/src/main/scala/cats/instances/anyval.scala @@ -22,6 +22,8 @@ package cats package instances +abstract private[instances] class AbstractAnyValInstances extends AbstractTupleInstances with AnyValInstances + trait AnyValInstances extends IntInstances with ByteInstances diff --git a/core/src/main/scala/cats/instances/either.scala b/core/src/main/scala/cats/instances/either.scala index a7a84bc5ed..2267f86241 100644 --- a/core/src/main/scala/cats/instances/either.scala +++ b/core/src/main/scala/cats/instances/either.scala @@ -58,7 +58,11 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances { implicit def catsStdInstancesForEither[A] : MonadError[Either[A, *], A] & Traverse[Either[A, *]] & Align[Either[A, *]] = - new MonadError[Either[A, *], A] with Traverse[Either[A, *]] with Align[Either[A, *]] { + new FlatMap.FoldableFlatMap[Either[A, *]] + with MonadError[Either[A, *], A] + with Traverse[Either[A, *]] + with Align[Either[A, *]] { + override def unit: Either[A, Unit] = Either.unit def pure[B](b: B): Either[A, B] = Right(b) diff --git a/core/src/main/scala/cats/instances/function.scala b/core/src/main/scala/cats/instances/function.scala index af1849307e..dec8d4a2cd 100644 --- a/core/src/main/scala/cats/instances/function.scala +++ b/core/src/main/scala/cats/instances/function.scala @@ -88,7 +88,7 @@ private[instances] trait FunctionInstancesBinCompat0 { sealed private[instances] trait Function0Instances extends Function0Instances0 { implicit val catsStdBimonadForFunction0: Bimonad[Function0] = - new Bimonad[Function0] { + new FlatMap.AbstractFlatMap[Function0] with Bimonad[Function0] { def extract[A](x: () => A): A = x() def coflatMap[A, B](fa: () => A)(f: (() => A) => B): () => B = @@ -148,7 +148,7 @@ sealed private[instances] trait Function1Instances extends Function1Instances0 { } implicit def catsStdMonadForFunction1[T1]: Monad[T1 => *] = - new Monad[T1 => *] { + new FlatMap.AbstractFlatMap[T1 => *] with Monad[T1 => *] { def pure[R](r: R): T1 => R = _ => r def flatMap[R1, R2](fa: T1 => R1)(f: R1 => T1 => R2): T1 => R2 = diff --git a/core/src/main/scala/cats/instances/future.scala b/core/src/main/scala/cats/instances/future.scala index cb38dc845c..30ae6c6a80 100644 --- a/core/src/main/scala/cats/instances/future.scala +++ b/core/src/main/scala/cats/instances/future.scala @@ -37,9 +37,15 @@ import scala.util.{Failure, Success} trait FutureInstances extends FutureInstances1 { implicit def catsStdInstancesForFuture(implicit - ec: ExecutionContext + ctx: ExecutionContext ): MonadThrow[Future] & CoflatMap[Future] & Monad[Future] = - new FutureCoflatMap with MonadThrow[Future] with Monad[Future] with StackSafeMonad[Future] { + new FlatMap.AbstractFlatMap[Future] + with FutureCoflatMap + with MonadThrow[Future] + with Monad[Future] + with StackSafeMonad[Future] { + + override def ec: ExecutionContext = ctx override def pure[A](x: A): Future[A] = Future.successful(x) override def flatMap[A, B](fa: Future[A])(f: A => Future[B]): Future[B] = @@ -87,7 +93,8 @@ sealed private[instances] trait FutureInstances2 { new FutureSemigroup[A] } -abstract private[cats] class FutureCoflatMap(implicit ec: ExecutionContext) extends CoflatMap[Future] { +private[cats] trait FutureCoflatMap extends CoflatMap[Future] { + implicit def ec: ExecutionContext def map[A, B](fa: Future[A])(f: A => B): Future[B] = fa.map(f) def coflatMap[A, B](fa: Future[A])(f: Future[A] => B): Future[B] = Future(f(fa)) } diff --git a/core/src/main/scala/cats/instances/list.scala b/core/src/main/scala/cats/instances/list.scala index 72beb2b318..18307b36c2 100644 --- a/core/src/main/scala/cats/instances/list.scala +++ b/core/src/main/scala/cats/instances/list.scala @@ -35,7 +35,13 @@ trait ListInstances extends cats.kernel.instances.ListInstances { implicit val catsStdInstancesForList : Traverse[List] & Alternative[List] & Monad[List] & CoflatMap[List] & Align[List] = - new Traverse[List] with Alternative[List] with Monad[List] with CoflatMap[List] with Align[List] { + new FlatMap.FoldableFlatMap[List] + with Traverse[List] + with Alternative[List] + with Monad[List] + with CoflatMap[List] + with Align[List] { + def empty[A]: List[A] = Nil def combineK[A](x: List[A], y: List[A]): List[A] = x ::: y diff --git a/core/src/main/scala/cats/instances/map.scala b/core/src/main/scala/cats/instances/map.scala index dfcc960bac..b06c160447 100644 --- a/core/src/main/scala/cats/instances/map.scala +++ b/core/src/main/scala/cats/instances/map.scala @@ -37,7 +37,7 @@ trait MapInstances extends cats.kernel.instances.MapInstances { .mkString("Map(", ", ", ")") implicit def catsStdInstancesForMap[K]: UnorderedTraverse[Map[K, *]] & FlatMap[Map[K, *]] & Align[Map[K, *]] = - new UnorderedTraverse[Map[K, *]] with FlatMap[Map[K, *]] with Align[Map[K, *]] { + new FlatMap.AbstractFlatMap[Map[K, *]] with UnorderedTraverse[Map[K, *]] with Align[Map[K, *]] { def unorderedTraverse[G[_], A, B]( fa: Map[K, A] diff --git a/core/src/main/scala/cats/instances/option.scala b/core/src/main/scala/cats/instances/option.scala index 32a005390b..7191163ef4 100644 --- a/core/src/main/scala/cats/instances/option.scala +++ b/core/src/main/scala/cats/instances/option.scala @@ -31,7 +31,8 @@ trait OptionInstances extends cats.kernel.instances.OptionInstances { implicit val catsStdInstancesForOption: Traverse[Option] & MonadError[Option, Unit] & Alternative[ Option ] & CommutativeMonad[Option] & CoflatMap[Option] & Align[Option] = - new Traverse[Option] + new FlatMap.FoldableFlatMap[Option] + with Traverse[Option] with MonadError[Option, Unit] with Alternative[Option] with CommutativeMonad[Option] diff --git a/core/src/main/scala/cats/instances/queue.scala b/core/src/main/scala/cats/instances/queue.scala index 88c4397ef6..828624ff24 100644 --- a/core/src/main/scala/cats/instances/queue.scala +++ b/core/src/main/scala/cats/instances/queue.scala @@ -34,7 +34,12 @@ import scala.util.Try trait QueueInstances extends cats.kernel.instances.QueueInstances { implicit val catsStdInstancesForQueue: Traverse[Queue] & Alternative[Queue] & Monad[Queue] & CoflatMap[Queue] = - new Traverse[Queue] with Alternative[Queue] with Monad[Queue] with CoflatMap[Queue] { + new FlatMap.FoldableFlatMap[Queue] + with Traverse[Queue] + with Alternative[Queue] + with Monad[Queue] + with CoflatMap[Queue] { + def empty[A]: Queue[A] = Queue.empty def combineK[A](x: Queue[A], y: Queue[A]): Queue[A] = x ++ y diff --git a/core/src/main/scala/cats/instances/seq.scala b/core/src/main/scala/cats/instances/seq.scala index 878c04f234..5683cc0876 100644 --- a/core/src/main/scala/cats/instances/seq.scala +++ b/core/src/main/scala/cats/instances/seq.scala @@ -33,7 +33,12 @@ import scala.collection.immutable.Seq @suppressUnusedImportWarningForScalaVersionSpecific trait SeqInstances extends cats.kernel.instances.SeqInstances { implicit val catsStdInstancesForSeq: Traverse[Seq] & Monad[Seq] & Alternative[Seq] & CoflatMap[Seq] & Align[Seq] = - new Traverse[Seq] with Monad[Seq] with Alternative[Seq] with CoflatMap[Seq] with Align[Seq] { + new FlatMap.FoldableFlatMap[Seq] + with Traverse[Seq] + with Monad[Seq] + with Alternative[Seq] + with CoflatMap[Seq] + with Align[Seq] { def empty[A]: Seq[A] = Seq.empty[A] diff --git a/core/src/main/scala/cats/instances/sortedMap.scala b/core/src/main/scala/cats/instances/sortedMap.scala index e15b22ece2..d39043c77b 100644 --- a/core/src/main/scala/cats/instances/sortedMap.scala +++ b/core/src/main/scala/cats/instances/sortedMap.scala @@ -50,7 +50,7 @@ trait SortedMapInstances extends SortedMapInstances2 { implicit def catsStdInstancesForSortedMap[K] : Traverse[SortedMap[K, *]] & FlatMap[SortedMap[K, *]] & Align[SortedMap[K, *]] = - new Traverse[SortedMap[K, *]] with FlatMap[SortedMap[K, *]] with Align[SortedMap[K, *]] { + new FlatMap.FoldableFlatMap[SortedMap[K, *]] with Traverse[SortedMap[K, *]] with Align[SortedMap[K, *]] { def traverse[G[_], A, B](fa: SortedMap[K, A])(f: A => G[B])(implicit G: Applicative[G]): G[SortedMap[K, B]] = { implicit val ordering: Ordering[K] = fa.ordering diff --git a/core/src/main/scala/cats/instances/sortedSet.scala b/core/src/main/scala/cats/instances/sortedSet.scala index c835601fc3..53fcbca04f 100644 --- a/core/src/main/scala/cats/instances/sortedSet.scala +++ b/core/src/main/scala/cats/instances/sortedSet.scala @@ -29,7 +29,7 @@ import scala.annotation.tailrec trait SortedSetInstances extends SortedSetInstances1 { implicit val catsStdInstancesForSortedSet: Foldable[SortedSet] & SemigroupK[SortedSet] = - new Foldable[SortedSet] with SemigroupK[SortedSet] { + new Foldable.AbstractFoldable[SortedSet] with SemigroupK[SortedSet] { def combineK[A](x: SortedSet[A], y: SortedSet[A]): SortedSet[A] = x | y diff --git a/core/src/main/scala/cats/instances/tailrec.scala b/core/src/main/scala/cats/instances/tailrec.scala index 7fb4fbe684..3e332dae67 100644 --- a/core/src/main/scala/cats/instances/tailrec.scala +++ b/core/src/main/scala/cats/instances/tailrec.scala @@ -31,7 +31,7 @@ trait TailRecInstances { private object TailRecInstances { val catsInstancesForTailRec: StackSafeMonad[TailRec] & Defer[TailRec] = - new StackSafeMonad[TailRec] with Defer[TailRec] { + new FlatMap.AbstractFlatMap[TailRec] with StackSafeMonad[TailRec] with Defer[TailRec] { def defer[A](fa: => TailRec[A]): TailRec[A] = tailcall(fa) def pure[A](a: A): TailRec[A] = done(a) diff --git a/core/src/main/scala/cats/instances/try.scala b/core/src/main/scala/cats/instances/try.scala index 8a69e752b1..c2cf4ac03c 100644 --- a/core/src/main/scala/cats/instances/try.scala +++ b/core/src/main/scala/cats/instances/try.scala @@ -31,7 +31,7 @@ import scala.annotation.tailrec trait TryInstances extends TryInstances1 { implicit def catsStdInstancesForTry: MonadThrow[Try] & CoflatMap[Try] & Traverse[Try] & Monad[Try] = - new TryCoflatMap with MonadThrow[Try] with Traverse[Try] with Monad[Try] { + new FlatMap.FoldableFlatMap[Try] with TryCoflatMap with MonadThrow[Try] with Traverse[Try] with Monad[Try] { def pure[A](x: A): Try[A] = Success(x) override def product[A, B](ta: Try[A], tb: Try[B]): Try[(A, B)] = @@ -213,7 +213,7 @@ sealed private[instances] trait TryInstances2 { new TrySemigroup[A] } -abstract private[cats] class TryCoflatMap extends CoflatMap[Try] { +private[cats] trait TryCoflatMap extends CoflatMap[Try] { def map[A, B](ta: Try[A])(f: A => B): Try[B] = ta.map(f) def coflatMap[A, B](ta: Try[A])(f: Try[A] => B): Try[B] = Try(f(ta)) } diff --git a/core/src/main/scala/cats/instances/tuple.scala b/core/src/main/scala/cats/instances/tuple.scala index eb47d7bae4..934a69aedc 100644 --- a/core/src/main/scala/cats/instances/tuple.scala +++ b/core/src/main/scala/cats/instances/tuple.scala @@ -27,6 +27,7 @@ import cats.kernel.{CommutativeMonoid, CommutativeSemigroup} import scala.annotation.tailrec trait TupleInstances extends Tuple2Instances with cats.kernel.instances.TupleInstances +abstract private[instances] class AbstractTupleInstances extends TupleInstances private[instances] trait Tuple2InstancesBinCompat0 { @@ -76,7 +77,7 @@ sealed private[instances] trait Tuple2Instances extends Tuple2Instances1 { @deprecated("Use catsStdInstancesForTuple2 in cats.instances.NTupleMonadInstances", "2.4.0") def catsStdInstancesForTuple2[X]: Traverse[(X, *)] & Comonad[(X, *)] & Reducible[(X, *)] = - new Traverse[(X, *)] with Comonad[(X, *)] with Reducible[(X, *)] { + new Foldable.AbstractFoldable[(X, *)] with Traverse[(X, *)] with Comonad[(X, *)] with Reducible[(X, *)] { def traverse[G[_], A, B](fa: (X, A))(f: A => G[B])(implicit G: Applicative[G]): G[(X, B)] = G.map(f(fa._2))((fa._1, _)) @@ -165,7 +166,7 @@ sealed private[instances] trait Tuple2Instances4 { new FlatMapTuple2[X](SX) } -private[instances] class FlatMapTuple2[X](s: Semigroup[X]) extends FlatMap[(X, *)] { +private[instances] class FlatMapTuple2[X](s: Semigroup[X]) extends FlatMap.AbstractFlatMap[(X, *)] { override def ap[A, B](ff: (X, A => B))(fa: (X, A)): (X, B) = { val x = s.combine(ff._1, fa._1) val b = ff._2(fa._2) diff --git a/core/src/main/scala/cats/instances/vector.scala b/core/src/main/scala/cats/instances/vector.scala index c1aad817c9..14c079b92c 100644 --- a/core/src/main/scala/cats/instances/vector.scala +++ b/core/src/main/scala/cats/instances/vector.scala @@ -32,7 +32,12 @@ import scala.collection.immutable.VectorBuilder trait VectorInstances extends cats.kernel.instances.VectorInstances { implicit val catsStdInstancesForVector : Traverse[Vector] & Monad[Vector] & Alternative[Vector] & CoflatMap[Vector] & Align[Vector] = - new Traverse[Vector] with Monad[Vector] with Alternative[Vector] with CoflatMap[Vector] with Align[Vector] { + new FlatMap.FoldableFlatMap[Vector] + with Traverse[Vector] + with Monad[Vector] + with Alternative[Vector] + with CoflatMap[Vector] + with Align[Vector] { def empty[A]: Vector[A] = Vector.empty[A] diff --git a/core/src/main/scala/cats/package.scala b/core/src/main/scala/cats/package.scala index 0a86548034..5c3502284c 100644 --- a/core/src/main/scala/cats/package.scala +++ b/core/src/main/scala/cats/package.scala @@ -97,7 +97,12 @@ package object cats { type Endo[A] = A => A val catsInstancesForId: Bimonad[Id] & CommutativeMonad[Id] & NonEmptyTraverse[Id] & Distributive[Id] = - new Bimonad[Id] with CommutativeMonad[Id] with NonEmptyTraverse[Id] with Distributive[Id] { + new FlatMap.FoldableFlatMap[Id] + with Bimonad[Id] + with CommutativeMonad[Id] + with NonEmptyTraverse[Id] + with Distributive[Id] { + def pure[A](a: A): A = a def extract[A](a: A): A = a def flatMap[A, B](a: A)(f: A => B): B = f(a) diff --git a/free/src/main/scala/cats/free/Cofree.scala b/free/src/main/scala/cats/free/Cofree.scala index 8802848806..5c7769d157 100644 --- a/free/src/main/scala/cats/free/Cofree.scala +++ b/free/src/main/scala/cats/free/Cofree.scala @@ -179,10 +179,10 @@ private trait CofreeComonad[S[_]] extends Comonad[Cofree[S, *]] { final override def coflatten[A](a: Cofree[S, A]): Cofree[S, Cofree[S, A]] = a.coflatten - final override def map[A, B](a: Cofree[S, A])(f: A => B): Cofree[S, B] = a.map(f) + override def map[A, B](a: Cofree[S, A])(f: A => B): Cofree[S, B] = a.map(f) } -private trait CofreeReducible[F[_]] extends Reducible[Cofree[F, *]] { +private trait CofreeReducible[F[_]] extends Foldable.AbstractFoldable[Cofree[F, *]] with Reducible[Cofree[F, *]] { implicit def F: Foldable[F] final override def foldMap[A, B](fa: Cofree[F, A])(f: A => B)(implicit M: Monoid[B]): B = @@ -207,10 +207,12 @@ private trait CofreeReducible[F[_]] extends Reducible[Cofree[F, *]] { } -private trait CofreeTraverse[F[_]] extends Traverse[Cofree[F, *]] with CofreeReducible[F] with CofreeComonad[F] { +private trait CofreeTraverse[F[_]] extends CofreeReducible[F] with CofreeComonad[F] with Traverse[Cofree[F, *]] { implicit def F: Traverse[F] + override def map[A, B](fa: Cofree[F, A])(f: A => B): Cofree[F, B] = + super[CofreeComonad].map(fa)(f) + final override def traverse[G[_], A, B](fa: Cofree[F, A])(f: A => G[B])(implicit G: Applicative[G]): G[Cofree[F, B]] = G.map2(f(fa.head), F.traverse(fa.tailForced)(traverse(_)(f)))((h, t) => Cofree[F, B](h, Eval.now(t))) - } diff --git a/free/src/main/scala/cats/free/Free.scala b/free/src/main/scala/cats/free/Free.scala index f2a86397e4..ff79120787 100644 --- a/free/src/main/scala/cats/free/Free.scala +++ b/free/src/main/scala/cats/free/Free.scala @@ -339,7 +339,7 @@ object Free extends FreeInstances { implicit def catsFreeDeferForId: Defer[Free[Id, *]] = catsFreeDeferForFree[Id] } -private trait FreeFoldable[F[_]] extends Foldable[Free[F, *]] { +private trait FreeFoldable[F[_]] extends Foldable.AbstractFoldable[Free[F, *]] { implicit def F: Foldable[F] @@ -350,7 +350,7 @@ private trait FreeFoldable[F[_]] extends Foldable[Free[F, *]] { fa.foldRight(fa, lb)(f) } -private trait FreeTraverse[F[_]] extends Traverse[Free[F, *]] with FreeFoldable[F] { +private trait FreeTraverse[F[_]] extends FreeFoldable[F] with Traverse[Free[F, *]] { implicit def TraversableF: Traverse[F] def F: Foldable[F] = TraversableF @@ -371,7 +371,7 @@ sealed abstract private[free] class FreeInstances extends FreeInstances1 with Fr * `Free[S, *]` has a monad for any type constructor `S[_]`. */ implicit def catsFreeMonadForFree[S[_]]: Monad[Free[S, *]] = - new Monad[Free[S, *]] with StackSafeMonad[Free[S, *]] { + new FlatMap.AbstractFlatMap[Free[S, *]] with Monad[Free[S, *]] with StackSafeMonad[Free[S, *]] { def pure[A](a: A): Free[S, A] = Free.pure(a) override def map[A, B](fa: Free[S, A])(f: A => B): Free[S, B] = fa.map(f) def flatMap[A, B](a: Free[S, A])(f: A => Free[S, B]): Free[S, B] = a.flatMap(f) diff --git a/free/src/main/scala/cats/free/FreeApplicative.scala b/free/src/main/scala/cats/free/FreeApplicative.scala index 851804dcac..78f733cf1d 100644 --- a/free/src/main/scala/cats/free/FreeApplicative.scala +++ b/free/src/main/scala/cats/free/FreeApplicative.scala @@ -223,7 +223,7 @@ object FreeApplicative { Lift(fa) implicit final def freeApplicative[S[_]]: Applicative[FA[S, *]] = - new Applicative[FA[S, *]] { + new Apply.AbstractApply[FA[S, *]] with Applicative[FA[S, *]] { override def product[A, B](fa: FA[S, A], fb: FA[S, B]): FA[S, (A, B)] = map2(fa, fb)((_, _)) diff --git a/free/src/main/scala/cats/free/FreeT.scala b/free/src/main/scala/cats/free/FreeT.scala index 9bd573ebdd..a447a7af15 100644 --- a/free/src/main/scala/cats/free/FreeT.scala +++ b/free/src/main/scala/cats/free/FreeT.scala @@ -274,7 +274,7 @@ sealed abstract private[free] class FreeTInstances extends FreeTInstances0 { 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] { + new FreeTMonad[S, M] with MonadError[FreeT[S, M, *], E] { override def M: Applicative[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) @@ -293,7 +293,7 @@ sealed abstract private[free] class FreeTInstances extends FreeTInstances0 { E: MonadError[M, E], S: Functor[S] ): MonadError[FreeT[S, M, *], E] = - new MonadError[FreeT[S, M, *], E] with FreeTMonad[S, M] { + new FreeTMonad[S, M] with MonadError[FreeT[S, M, *], E] { override def M: Applicative[M] = E private[this] val RealDefer = catsDeferForFreeT[S, M] @@ -361,7 +361,7 @@ sealed abstract private[free] class FreeTInstances1 extends FreeTInstances2 { sealed abstract private[free] class 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] { + new FreeTMonad[S, M] with FreeTMonoidK[S, M] with Alternative[FreeT[S, M, *]] { override def M: Applicative[M] = Alternative[M] override def M1: MonoidK[M] = Alternative[M] } @@ -375,20 +375,23 @@ sealed abstract private[free] class FreeTInstances3 { } } -sealed private[free] trait FreeTFlatMap[S[_], M[_]] extends FlatMap[FreeT[S, M, *]] { +sealed private[free] trait FreeTFlatMap[S[_], M[_]] extends FlatMap.AbstractFlatMap[FreeT[S, M, *]] { implicit def M: Applicative[M] - final override def map[A, B](fa: FreeT[S, M, A])(f: A => B): FreeT[S, M, B] = fa.map(f) + override def map[A, B](fa: FreeT[S, M, A])(f: A => B): FreeT[S, M, B] = fa.map(f) def flatMap[A, B](fa: FreeT[S, M, A])(f: A => FreeT[S, M, B]): FreeT[S, M, B] = fa.flatMap(f) final override def tailRecM[A, B](a: A)(f: A => FreeT[S, M, Either[A, B]]): FreeT[S, M, B] = FreeT.tailRecM(a)(f) } -sealed private[free] trait FreeTMonad[S[_], M[_]] extends Monad[FreeT[S, M, *]] with FreeTFlatMap[S, M] { +sealed private[free] trait FreeTMonad[S[_], M[_]] extends FreeTFlatMap[S, M] with Monad[FreeT[S, M, *]] { implicit def M: Applicative[M] final override def pure[A](a: A): FreeT[S, M, A] = FreeT.pure[S, M, A](a) + + override def map[A, B](fa: FreeT[S, M, A])(f: A => B) = + super[FreeTFlatMap].map(fa)(f) } sealed private[free] trait FreeTMonoidK[S[_], M[_]] extends MonoidK[FreeT[S, M, *]] with FreeTSemigroupK[S, M] { diff --git a/free/src/test/scala-2.13+/cats/free/FreeStructuralSuite.scala b/free/src/test/scala-2.13+/cats/free/FreeStructuralSuite.scala index 7d06af41d5..6e8deed2b4 100644 --- a/free/src/test/scala-2.13+/cats/free/FreeStructuralSuite.scala +++ b/free/src/test/scala-2.13+/cats/free/FreeStructuralSuite.scala @@ -21,11 +21,10 @@ package cats.free -import cats.{Applicative, Eq, Eval, Functor, Show, Traverse} +import cats.{Applicative, Eq, Eval, Foldable, Functor, Show, Traverse} import cats.kernel.laws.discipline.{EqTests, HashTests, PartialOrderTests} import cats.syntax.all.* import cats.tests.CatsSuite - import org.scalacheck.{Arbitrary, Cogen, Gen} // this functionality doesn't exist on Scala 2.12 @@ -70,7 +69,7 @@ object FreeStructuralSuite { } implicit def traverse: Traverse[ExprF] = - new Traverse[ExprF] { + new Foldable.AbstractFoldable[ExprF] with Traverse[ExprF] { def foldLeft[A, B](fa: ExprF[A], b: B)(f: (B, A) => B): B = fa match { diff --git a/laws/src/main/scala/cats/laws/NonEmptyTraverseLaws.scala b/laws/src/main/scala/cats/laws/NonEmptyTraverseLaws.scala index 4016396181..37ae450965 100644 --- a/laws/src/main/scala/cats/laws/NonEmptyTraverseLaws.scala +++ b/laws/src/main/scala/cats/laws/NonEmptyTraverseLaws.scala @@ -49,7 +49,7 @@ trait NonEmptyTraverseLaws[F[_]] extends TraverseLaws[F] with ReducibleLaws[F] { g: A => N[B] )(implicit N: Apply[N], M: Apply[M]): IsEq[(M[F[B]], N[F[B]])] = { type MN[Z] = (M[Z], N[Z]) - implicit val MN: Apply[MN] = new Apply[MN] { + implicit val MN: Apply[MN] = new Apply.AbstractApply[MN] { def ap[X, Y](f: MN[X => Y])(fa: MN[X]): MN[Y] = { val (fam, fan) = fa val (fm, fn) = f diff --git a/laws/src/main/scala/cats/laws/ShortCircuitingLaws.scala b/laws/src/main/scala/cats/laws/ShortCircuitingLaws.scala index 495288f223..aa379a1cd7 100644 --- a/laws/src/main/scala/cats/laws/ShortCircuitingLaws.scala +++ b/laws/src/main/scala/cats/laws/ShortCircuitingLaws.scala @@ -22,13 +22,12 @@ package cats.laws import java.util.concurrent.atomic.AtomicLong - import cats.instances.option.* import cats.syntax.foldable.* import cats.syntax.traverse.* import cats.syntax.nonEmptyTraverse.* import cats.syntax.traverseFilter.* -import cats.{Applicative, Foldable, MonoidK, NonEmptyTraverse, Traverse, TraverseFilter} +import cats.{Applicative, Apply, Foldable, MonoidK, NonEmptyTraverse, Traverse, TraverseFilter} trait ShortCircuitingLaws[F[_]] { @@ -140,7 +139,8 @@ trait ShortCircuitingLaws[F[_]] { empty } - private[this] val nonShortCircuitingApplicative: Applicative[Option] = new Applicative[Option] { + private[this] val nonShortCircuitingApplicative: Applicative[Option] = new Apply.AbstractApply[Option] + with Applicative[Option] { override def pure[A](a: A): Option[A] = Some(a) override def ap[A, B](ff: Option[A => B])(fa: Option[A]): Option[B] = ff.flatMap(f => fa.map(f)) } diff --git a/laws/src/main/scala/cats/laws/TraverseLaws.scala b/laws/src/main/scala/cats/laws/TraverseLaws.scala index 5c9bb7d952..d2c899f550 100644 --- a/laws/src/main/scala/cats/laws/TraverseLaws.scala +++ b/laws/src/main/scala/cats/laws/TraverseLaws.scala @@ -50,7 +50,7 @@ trait TraverseLaws[F[_]] extends FunctorLaws[F] with FoldableLaws[F] with Unorde g: A => N[B] )(implicit N: Applicative[N], M: Applicative[M]): IsEq[(M[F[B]], N[F[B]])] = { type MN[Z] = (M[Z], N[Z]) - implicit val MN: Applicative[MN] = new Applicative[MN] { + implicit val MN: Applicative[MN] = new Apply.AbstractApply[MN] with Applicative[MN] { def pure[X](x: X): MN[X] = (M.pure(x), N.pure(x)) def ap[X, Y](f: MN[X => Y])(fa: MN[X]): MN[Y] = { val (fam, fan) = fa diff --git a/laws/src/main/scala/cats/laws/UnorderedTraverseLaws.scala b/laws/src/main/scala/cats/laws/UnorderedTraverseLaws.scala index 7a41a0fae7..ab9410cc46 100644 --- a/laws/src/main/scala/cats/laws/UnorderedTraverseLaws.scala +++ b/laws/src/main/scala/cats/laws/UnorderedTraverseLaws.scala @@ -46,7 +46,7 @@ trait UnorderedTraverseLaws[F[_]] extends UnorderedFoldableLaws[F] { ): IsEq[(M[F[B]], N[F[B]])] = { type MN[Z] = (M[Z], N[Z]) - implicit val MN: CommutativeApplicative[MN] = new CommutativeApplicative[MN] { + implicit val MN: CommutativeApplicative[MN] = new Apply.AbstractApply[MN] with CommutativeApplicative[MN] { def pure[X](x: X): MN[X] = (M.pure(x), N.pure(x)) def ap[X, Y](f: MN[X => Y])(fa: MN[X]): MN[Y] = { val (fam, fan) = fa diff --git a/mima.sbt b/mima.sbt index 4571afdc5c..af38fe3d6e 100644 --- a/mima.sbt +++ b/mima.sbt @@ -1,7 +1,7 @@ import com.typesafe.tools.mima.core.ProblemFilters._ import com.typesafe.tools.mima.core._ -ThisBuild / mimaBinaryIssueFilters ++= { +ThisBuild / mimaBinaryIssueFilters ++= Seq.concat( // These things are Ops classes that shouldn't have the `value` exposed. These should have never been public because they don't // provide any value. Making them private because of issues like #2514 and #2613. Seq( @@ -86,79 +86,86 @@ ThisBuild / mimaBinaryIssueFilters ++= { exclude[DirectMissingMethodProblem]("cats.syntax.ValidatedIdSyntax.a"), exclude[DirectMissingMethodProblem]("cats.syntax.VectorOps.va"), exclude[DirectMissingMethodProblem]("cats.syntax.WriterIdSyntax.a") - ) ++ // Only compile-time abstractions (macros) allowed here - Seq( - exclude[IncompatibleMethTypeProblem]("cats.arrow.FunctionKMacros.lift"), - exclude[MissingTypesProblem]("cats.arrow.FunctionKMacros$"), - exclude[IncompatibleMethTypeProblem]("cats.arrow.FunctionKMacros#Lifter.this"), - exclude[IncompatibleResultTypeProblem]("cats.arrow.FunctionKMacros#Lifter.c"), - exclude[DirectMissingMethodProblem]("cats.arrow.FunctionKMacros.compatNewTypeName") - ) ++ // package private classes no longer needed - Seq( - exclude[MissingClassProblem]("cats.kernel.compat.scalaVersionMoreSpecific$"), - exclude[MissingClassProblem]("cats.kernel.compat.scalaVersionMoreSpecific"), - exclude[MissingClassProblem]( - "cats.kernel.compat.scalaVersionMoreSpecific$suppressUnusedImportWarningForScalaVersionMoreSpecific" - ) - ) ++ // New issues found since mima 0.8.0 (#3596, #3641) - Seq( - exclude[NewMixinForwarderProblem]("cats.kernel.Band#mcI#sp.combineN"), - exclude[NewMixinForwarderProblem]("cats.kernel.Band#mcD#sp.combineN"), - exclude[NewMixinForwarderProblem]("cats.kernel.Band#mcJ#sp.combineN"), - exclude[NewMixinForwarderProblem]("cats.kernel.Band.combineN"), - exclude[NewMixinForwarderProblem]("cats.kernel.Band#mcF#sp.combineN") - ) ++ // Additional methods in package-private traits - Seq( - exclude[ReversedMissingMethodProblem]("cats.data.NonEmptyCollection.grouped") - ) ++ // https://github.com/typelevel/cats/pull/3785 - Seq( - exclude[MissingClassProblem]("cats.syntax.EqOps$mcJ$sp"), - exclude[MissingClassProblem]("cats.syntax.EqOps$mcD$sp"), - exclude[FinalClassProblem]("cats.syntax.EqOps"), - exclude[MissingFieldProblem]("cats.syntax.EqOps.lhs"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.unapply"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.apply"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.lhs"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy$default$1"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productPrefix"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productArity"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productElement"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productIterator"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.canEqual"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy$default$1$mcD$sp"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy$default$1$mcF$sp"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy$default$1$mcJ$sp"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy$default$1$mcI$sp"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productElementNames"), - exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productElementName"), - exclude[MissingClassProblem]("cats.syntax.EqOps$"), - exclude[MissingClassProblem]("cats.syntax.EqOps$mcF$sp"), - exclude[MissingClassProblem]("cats.syntax.EqOps$mcI$sp") - ) ++ // https://github.com/typelevel/cats/pull/3918 - Seq( - exclude[MissingClassProblem]("algebra.laws.IsSerializable"), - exclude[MissingClassProblem]("algebra.laws.IsSerializable$") - ) ++ // https://github.com/typelevel/cats/pull/3987 - Seq( - exclude[DirectAbstractMethodProblem]("cats.free.ContravariantCoyoneda.k"), - exclude[ReversedAbstractMethodProblem]("cats.free.ContravariantCoyoneda.k"), - exclude[DirectAbstractMethodProblem]("cats.free.Coyoneda.k"), - exclude[ReversedAbstractMethodProblem]("cats.free.Coyoneda.k") - ) ++ // https://github.com/typelevel/cats/pull/4315 - Seq( - exclude[MissingClassProblem]("cats.compat.compat$package"), - exclude[MissingClassProblem]("cats.compat.compat$package$"), - ProblemFilters.exclude[MissingClassProblem]("cats.compat.targetName") - ) ++ // scala 3 specific filters - Seq( - exclude[DirectMissingMethodProblem]("cats.free.ContravariantCoyoneda.unsafeApply"), - exclude[DirectMissingMethodProblem]("cats.free.Coyoneda.unsafeApply") - ) ++ Seq( - ProblemFilters.exclude[MissingClassProblem]("cats.compat.package"), - ProblemFilters.exclude[MissingClassProblem]("cats.compat.package$") - ) ++ Seq( // PR#4682 - // Renamed to `cats.Traverse.traverseVoidDirectly` - ProblemFilters.exclude[DirectMissingMethodProblem]("cats.Traverse.traverse_Directly") + ), // Only compile-time abstractions (macros) allowed here + Seq( + exclude[IncompatibleMethTypeProblem]("cats.arrow.FunctionKMacros.lift"), + exclude[MissingTypesProblem]("cats.arrow.FunctionKMacros$"), + exclude[IncompatibleMethTypeProblem]("cats.arrow.FunctionKMacros#Lifter.this"), + exclude[IncompatibleResultTypeProblem]("cats.arrow.FunctionKMacros#Lifter.c"), + exclude[DirectMissingMethodProblem]("cats.arrow.FunctionKMacros.compatNewTypeName") + ), // package private classes no longer needed + Seq( + exclude[MissingClassProblem]("cats.kernel.compat.scalaVersionMoreSpecific$"), + exclude[MissingClassProblem]("cats.kernel.compat.scalaVersionMoreSpecific"), + exclude[MissingClassProblem]( + "cats.kernel.compat.scalaVersionMoreSpecific$suppressUnusedImportWarningForScalaVersionMoreSpecific" ) -} + ), // New issues found since mima 0.8.0 (#3596, #3641) + Seq( + exclude[NewMixinForwarderProblem]("cats.kernel.Band#mcI#sp.combineN"), + exclude[NewMixinForwarderProblem]("cats.kernel.Band#mcD#sp.combineN"), + exclude[NewMixinForwarderProblem]("cats.kernel.Band#mcJ#sp.combineN"), + exclude[NewMixinForwarderProblem]("cats.kernel.Band.combineN"), + exclude[NewMixinForwarderProblem]("cats.kernel.Band#mcF#sp.combineN") + ), // Additional methods in package-private traits + Seq( + exclude[ReversedMissingMethodProblem]("cats.data.NonEmptyCollection.grouped") + ), // https://github.com/typelevel/cats/pull/3785 + Seq( + exclude[MissingClassProblem]("cats.syntax.EqOps$mcJ$sp"), + exclude[MissingClassProblem]("cats.syntax.EqOps$mcD$sp"), + exclude[FinalClassProblem]("cats.syntax.EqOps"), + exclude[MissingFieldProblem]("cats.syntax.EqOps.lhs"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.unapply"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.apply"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.lhs"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy$default$1"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productPrefix"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productArity"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productElement"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productIterator"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.canEqual"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy$default$1$mcD$sp"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy$default$1$mcF$sp"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy$default$1$mcJ$sp"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.copy$default$1$mcI$sp"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productElementNames"), + exclude[DirectMissingMethodProblem]("cats.syntax.EqOps.productElementName"), + exclude[MissingClassProblem]("cats.syntax.EqOps$"), + exclude[MissingClassProblem]("cats.syntax.EqOps$mcF$sp"), + exclude[MissingClassProblem]("cats.syntax.EqOps$mcI$sp") + ), // https://github.com/typelevel/cats/pull/3918 + Seq( + exclude[MissingClassProblem]("algebra.laws.IsSerializable"), + exclude[MissingClassProblem]("algebra.laws.IsSerializable$") + ), // https://github.com/typelevel/cats/pull/3987 + Seq( + exclude[DirectAbstractMethodProblem]("cats.free.ContravariantCoyoneda.k"), + exclude[ReversedAbstractMethodProblem]("cats.free.ContravariantCoyoneda.k"), + exclude[DirectAbstractMethodProblem]("cats.free.Coyoneda.k"), + exclude[ReversedAbstractMethodProblem]("cats.free.Coyoneda.k") + ), // https://github.com/typelevel/cats/pull/4315 + Seq( + exclude[MissingClassProblem]("cats.compat.compat$package"), + exclude[MissingClassProblem]("cats.compat.compat$package$"), + ProblemFilters.exclude[MissingClassProblem]("cats.compat.targetName") + ), // scala 3 specific filters + Seq( + exclude[DirectMissingMethodProblem]("cats.free.ContravariantCoyoneda.unsafeApply"), + exclude[DirectMissingMethodProblem]("cats.free.Coyoneda.unsafeApply") + ), + Seq( + ProblemFilters.exclude[MissingClassProblem]("cats.compat.package"), + ProblemFilters.exclude[MissingClassProblem]("cats.compat.package$") + ), + Seq( // PR#4682 + // Renamed to `cats.Traverse.traverseVoidDirectly` + ProblemFilters.exclude[DirectMissingMethodProblem]("cats.Traverse.traverse_Directly") + ), + Seq( // Private traits turned abstract classes + ProblemFilters.exclude[MissingTypesProblem]("cats.free.FreeFoldable"), + ProblemFilters.exclude[IncompatibleTemplateDefProblem]("cats.RepresentableBimonad"), + ProblemFilters.exclude[IncompatibleTemplateDefProblem]("cats.RepresentableMonad") + ) +) diff --git a/project/TupleMonadInstancesBoiler.scala b/project/TupleMonadInstancesBoiler.scala index 57074b2c0f..61a4bf6288 100644 --- a/project/TupleMonadInstancesBoiler.scala +++ b/project/TupleMonadInstancesBoiler.scala @@ -119,7 +119,7 @@ object GenTupleMonadInstances extends Template { |} - -private[instances] class $flatMapTupleClass${`[A0, A(N - 1)]`}(${`parameters A..(N-1)`("Semigroup")}) - - extends FlatMap[${`(A..N - 1, *)`}] { + - extends FlatMap.AbstractFlatMap[${`(A..N - 1, *)`}] { - override def ap[A, B](ff: ${`A0, A(N - 1)&`("A => B")})(fa: ${`A0, A(N - 1)&`("A")}) = - ${`combine A..(N - 1)`("ff", "fa", s"ff._$arity(fa._$arity)")} - override def product[A, B](fa: ${`A0, A(N - 1)&`("A")}, fb: ${`A0, A(N - 1)&`("B")}) = diff --git a/project/TupleUnorderedFoldableInstancesBoiler.scala b/project/TupleUnorderedFoldableInstancesBoiler.scala index 364f9498a5..5d51eef84d 100644 --- a/project/TupleUnorderedFoldableInstancesBoiler.scala +++ b/project/TupleUnorderedFoldableInstancesBoiler.scala @@ -23,7 +23,7 @@ object GenTupleUnorderedFoldableInstances extends Template { | private def instance[F[_] <: Product]( | trav: (F[Any], Applicative[γ], Any => γ[Any]) => γ[F[Any]] | ): Traverse[F] with Reducible[F] = - | new Traverse[F] with Reducible[F] { + | new Foldable.AbstractFoldable[F] with Traverse[F] with Reducible[F] { | def traverse[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Applicative[G]) = | trav(fa.asInstanceOf[F[Any]], G.asInstanceOf[Applicative[γ]], f.asInstanceOf[Any => γ[Any]]).asInstanceOf[G[F[B]]] | @inline private def last[A](fa: F[A]): A = diff --git a/testkit/src/main/scala/cats/tests/ListWrapper.scala b/testkit/src/main/scala/cats/tests/ListWrapper.scala index afb6db3e99..be2303624f 100644 --- a/testkit/src/main/scala/cats/tests/ListWrapper.scala +++ b/testkit/src/main/scala/cats/tests/ListWrapper.scala @@ -67,7 +67,7 @@ object ListWrapper { val traverse: Traverse[ListWrapper] = { val F = Traverse[List] - new Traverse[ListWrapper] { + new Foldable.AbstractFoldable[ListWrapper] with 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] = @@ -124,7 +124,7 @@ object ListWrapper { val alternative: Alternative[ListWrapper] = { val M = Alternative[List] - new Alternative[ListWrapper] { + new Apply.AbstractApply[ListWrapper] with Alternative[ListWrapper] { def pure[A](x: A): ListWrapper[A] = ListWrapper(M.pure(x)) def ap[A, B](f: ListWrapper[A => B])(fa: ListWrapper[A]): ListWrapper[B] = @@ -139,7 +139,7 @@ object ListWrapper { def nonEmptyAlternative: NonEmptyAlternative[ListWrapper] = alternative - val monad: Monad[ListWrapper] = new Monad[ListWrapper] { + val monad: Monad[ListWrapper] = new FlatMap.AbstractFlatMap[ListWrapper] with Monad[ListWrapper] { val M = Monad[List] def pure[A](x: A): ListWrapper[A] = ListWrapper(x :: Nil) diff --git a/tests/js/src/test/scala/cats/js/instances/future.scala b/tests/js/src/test/scala/cats/js/instances/future.scala index 6776e2944d..96ee03ac19 100644 --- a/tests/js/src/test/scala/cats/js/instances/future.scala +++ b/tests/js/src/test/scala/cats/js/instances/future.scala @@ -41,8 +41,9 @@ object Await { } sealed private[instances] trait FutureInstances0 extends FutureInstances1 { - def futureComonad(atMost: FiniteDuration)(implicit ec: E): Comonad[Future] = + def futureComonad(atMost: FiniteDuration)(implicit ctx: E): Comonad[Future] = new FutureCoflatMap with Comonad[Future] { + override def ec: E = ctx def extract[A](x: Future[A]): A = Await.result(x, atMost) } diff --git a/tests/shared/src/test/scala-2.13+/cats/tests/ScalaVersionSpecific.scala b/tests/shared/src/test/scala-2.13+/cats/tests/ScalaVersionSpecific.scala index 667255e2f1..ba612efb0e 100644 --- a/tests/shared/src/test/scala-2.13+/cats/tests/ScalaVersionSpecific.scala +++ b/tests/shared/src/test/scala-2.13+/cats/tests/ScalaVersionSpecific.scala @@ -78,7 +78,7 @@ trait ScalaVersionSpecificFoldableSuite { self: FoldableSuiteAdditional => } def foldableLazyListWithDefaultImpl: Foldable[LazyList] = - new Foldable[LazyList] { + new Foldable.AbstractFoldable[LazyList] { def foldLeft[A, B](fa: LazyList[A], b: B)(f: (B, A) => B): B = Foldable[LazyList].foldLeft(fa, b)(f) diff --git a/tests/shared/src/test/scala/cats/tests/ApplicativeErrorSuite.scala b/tests/shared/src/test/scala/cats/tests/ApplicativeErrorSuite.scala index 6b932f28a7..23207b862e 100644 --- a/tests/shared/src/test/scala/cats/tests/ApplicativeErrorSuite.scala +++ b/tests/shared/src/test/scala/cats/tests/ApplicativeErrorSuite.scala @@ -21,7 +21,7 @@ package cats.tests -import cats.ApplicativeError +import cats.{ApplicativeError, Apply} import cats.data.EitherT import cats.kernel.Eq import cats.syntax.applicativeError.* @@ -103,7 +103,7 @@ class ApplicativeErrorSuite extends CatsSuite { implicit def mayBeApplicativeError[E](implicit ev: ApplicativeError[Option, E] ): ApplicativeError[OptionWrapper, E] = - new ApplicativeError[OptionWrapper, E] { + new Apply.AbstractApply[OptionWrapper] with ApplicativeError[OptionWrapper, E] { def raiseError[A](e: E): OptionWrapper[A] = OptionWrapper(ev.raiseError(e)) diff --git a/tests/shared/src/test/scala/cats/tests/FoldableSuite.scala b/tests/shared/src/test/scala/cats/tests/FoldableSuite.scala index 256a6c3808..d15fecbc43 100644 --- a/tests/shared/src/test/scala/cats/tests/FoldableSuite.scala +++ b/tests/shared/src/test/scala/cats/tests/FoldableSuite.scala @@ -628,7 +628,7 @@ sealed trait FoldableSuiteAdditionalStreamSpecific { self: FoldableSuiteAddition } def foldableStreamWithDefaultImpl: Foldable[Stream] = - new Foldable[Stream] { + new Foldable.AbstractFoldable[Stream] { def foldLeft[A, B](fa: Stream[A], b: B)(f: (B, A) => B): B = Foldable[Stream].foldLeft(fa, b)(f) diff --git a/tests/shared/src/test/scala/cats/tests/ParallelSuite.scala b/tests/shared/src/test/scala/cats/tests/ParallelSuite.scala index dec980ec4e..77f913c900 100644 --- a/tests/shared/src/test/scala/cats/tests/ParallelSuite.scala +++ b/tests/shared/src/test/scala/cats/tests/ParallelSuite.scala @@ -472,7 +472,7 @@ class ParallelSuite } final case class Effect[A](value: A) - val monadInstance: Monad[Effect] = new Monad[Effect] { + val monadInstance: Monad[Effect] = new FlatMap.AbstractFlatMap[Effect] with Monad[Effect] { def pure[A](a: A): Effect[A] = Effect(a) def flatMap[A, B](fa: Effect[A])(f: A => Effect[B]): Effect[B] = throw Marker("sequential") def tailRecM[A, B](a: A)(f: A => Effect[Either[A, B]]): Effect[B] = ??? @@ -483,7 +483,7 @@ class ParallelSuite def sequential: Effect ~> Effect = arrow.FunctionK.id def applicative: Applicative[Effect] = - new Applicative[Effect] { + new Apply.AbstractApply[Effect] with Applicative[Effect] { def pure[A](a: A): Effect[A] = Effect(a) def ap[A, B](ff: Effect[A => B])(fa: Effect[A]): Effect[B] = throw Marker("parallel") } diff --git a/tests/shared/src/test/scala/cats/tests/ReducibleSuite.scala b/tests/shared/src/test/scala/cats/tests/ReducibleSuite.scala index 6ace3556bb..f4ab21a449 100644 --- a/tests/shared/src/test/scala/cats/tests/ReducibleSuite.scala +++ b/tests/shared/src/test/scala/cats/tests/ReducibleSuite.scala @@ -94,7 +94,7 @@ sealed trait ReducibleSuiteAdditionalStreamSpecific { self: ReducibleSuiteAdditi } object NES { - implicit val nesReducible: Reducible[NES] = new Reducible[NES] { + implicit val nesReducible: Reducible[NES] = new Foldable.AbstractFoldable[NES] with Reducible[NES] { def foldLeft[A, B](fa: NES[A], b: B)(f: (B, A) => B): B = fa.toStream.foldLeft(b)(f) def foldRight[A, B](fa: NES[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = (fa: @unchecked) match { diff --git a/tests/shared/src/test/scala/cats/tests/RegressionSuite.scala b/tests/shared/src/test/scala/cats/tests/RegressionSuite.scala index ede767c541..3ff31f7bb3 100644 --- a/tests/shared/src/test/scala/cats/tests/RegressionSuite.scala +++ b/tests/shared/src/test/scala/cats/tests/RegressionSuite.scala @@ -49,7 +49,7 @@ class RegressionSuite extends CatsSuite with ScalaVersionSpecificRegressionSuite object State { implicit def instance[S]: Monad[State[S, *]] = - new Monad[State[S, *]] with StackSafeMonad[State[S, *]] { // lies! + new FlatMap.AbstractFlatMap[State[S, *]] with Monad[State[S, *]] with StackSafeMonad[State[S, *]] { // lies! def pure[A](a: A): State[S, A] = State(s => (a, s)) def flatMap[A, B](sa: State[S, A])(f: A => State[S, B]): State[S, B] = sa.flatMap(f) } diff --git a/tests/shared/src/test/scala/cats/tests/TraverseSuite.scala b/tests/shared/src/test/scala/cats/tests/TraverseSuite.scala index 69d186ebfb..ca84a4c76c 100644 --- a/tests/shared/src/test/scala/cats/tests/TraverseSuite.scala +++ b/tests/shared/src/test/scala/cats/tests/TraverseSuite.scala @@ -109,7 +109,7 @@ object TraverseSuite { // proxies a traverse instance so we can test default implementations // to achieve coverage using default datatype instances private def proxyTraverse[F[_]: Traverse]: Traverse[F] = - new Traverse[F] { + new Foldable.AbstractFoldable[F] with Traverse[F] { def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B = Traverse[F].foldLeft(fa, b)(f) def foldRight[A, B](fa: F[A], lb: cats.Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =