diff --git a/core/src/main/scala-3/cats/derived/Derived.scala b/core/src/main/scala-3/cats/derived/Derived.scala index bff69f23..cae1f600 100644 --- a/core/src/main/scala-3/cats/derived/Derived.scala +++ b/core/src/main/scala-3/cats/derived/Derived.scala @@ -1,8 +1,9 @@ package cats.derived import shapeless3.deriving.* + import scala.annotation.* -import scala.compiletime.* +import scala.compiletime.summonFrom @implicitNotFound("Could not derive an instance of ${A}") opaque type Derived[A] = A @@ -29,6 +30,9 @@ object Derived: extension [I[f[_[_, _]], t[_, _]] <: K2.Instances[f, t], F[_[_, _]], T[_, _]](inst: I[Or2[F], T]) @targetName("unifyK2") def unify: I[F, T] = inst + abstract private[derived] class Lazy[A](f: () => A) extends Serializable: + final protected lazy val delegate: A = f() + sealed abstract class OrInstances: inline given [A]: Derived.Or[A] = summonFrom { case instance: A => Derived.Or(instance) diff --git a/core/src/main/scala-3/cats/derived/DerivedApplicative.scala b/core/src/main/scala-3/cats/derived/DerivedApplicative.scala index 45c05fa5..438782b6 100644 --- a/core/src/main/scala-3/cats/derived/DerivedApplicative.scala +++ b/core/src/main/scala-3/cats/derived/DerivedApplicative.scala @@ -1,13 +1,10 @@ package cats.derived -import shapeless3.deriving.{Const, K1} import cats.{Applicative, Monoid} - -import scala.compiletime.* -import shapeless3.deriving.{Continue, K0, Labelling} +import shapeless3.deriving.{Const, K1} import scala.annotation.implicitNotFound -import scala.deriving.Mirror +import scala.compiletime.* @implicitNotFound("""Could not derive an instance of Applicative[F] where F = ${F}. Make sure that F[_] satisfies one of the following conditions: @@ -23,17 +20,21 @@ object DerivedApplicative: summonInline[DerivedApplicative[F]].instance given [T](using T: Monoid[T]): DerivedApplicative[Const[T]] = new Applicative[Const[T]]: - def pure[A](x: A): Const[T][A] = T.empty - def ap[A, B](ff: T)(fa: T): Const[T][B] = T.combine(ff, fa) + def pure[A](x: A): T = T.empty + def ap[A, B](ff: T)(fa: T): T = T.combine(ff, fa) - given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedApplicative[[x] =>> F[G[x]]] = - F.unify.compose(G.unify) + given nested[F[_], G[_]](using F: => Or[F], G: => Or[G]): DerivedApplicative[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.compose(G.unify)) with Applicative[[x] =>> F[G[x]]]: + export delegate.* given [F[_]](using inst: => K1.ProductInstances[Or, F]): DerivedApplicative[F] = given K1.ProductInstances[Applicative, F] = inst.unify new Product[Applicative, F] with DerivedApply.Product[Applicative, F] {} - trait Product[T[x[_]] <: Applicative[x], F[_]](using inst: K1.ProductInstances[T, F]) + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedApplicative_F[F[_]: Or, G[_]: Or]: DerivedApplicative[[x] =>> F[G[x]]] = summon + + trait Product[T[f[_]] <: Applicative[f], F[_]](using inst: K1.ProductInstances[T, F]) extends Applicative[F], DerivedApply.Product[T, F]: - override def pure[A](x: A): F[A] = inst.construct([t[_]] => (apl: T[t]) => apl.pure[A](x)) + final override def pure[A](x: A): F[A] = inst.construct([f[_]] => (F: T[f]) => F.pure[A](x)) diff --git a/core/src/main/scala-3/cats/derived/DerivedApply.scala b/core/src/main/scala-3/cats/derived/DerivedApply.scala index 31f4b56b..76e711f0 100644 --- a/core/src/main/scala-3/cats/derived/DerivedApply.scala +++ b/core/src/main/scala-3/cats/derived/DerivedApply.scala @@ -1,13 +1,10 @@ package cats.derived -import shapeless3.deriving.{Const, K1} import cats.{Apply, Semigroup} - -import scala.compiletime.* -import shapeless3.deriving.{Continue, K0, Labelling} +import shapeless3.deriving.{Const, K1} import scala.annotation.implicitNotFound -import scala.deriving.Mirror +import scala.compiletime.* @implicitNotFound("""Could not derive an instance of Apply[F] where F = ${F}. Make sure that F[_] satisfies one of the following conditions: @@ -23,18 +20,22 @@ object DerivedApply: summonInline[DerivedApply[F]].instance given [T](using T: Semigroup[T]): DerivedApply[Const[T]] = new Apply[Const[T]]: - def ap[A, B](ff: T)(fa: T) = T.combine(ff, fa) - def map[A, B](fa: T)(f: A => B) = fa + def ap[A, B](ff: T)(fa: T): T = T.combine(ff, fa) + def map[A, B](fa: T)(f: A => B): T = fa - given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedApply[[x] =>> F[G[x]]] = - F.unify.compose(G.unify) + given nested[F[_], G[_]](using F: => Or[F], G: => Or[G]): DerivedApply[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.compose(G.unify)) with Apply[[x] =>> F[G[x]]]: + export delegate.* given [F[_]](using inst: => K1.ProductInstances[Or, F]): DerivedApply[F] = given K1.ProductInstances[Apply, F] = inst.unify new Product[Apply, F] {} - trait Product[T[x[_]] <: Apply[x], F[_]](using inst: K1.ProductInstances[T, F]) extends Apply[F]: - override def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] = - inst.map2(ff, fa)([t[_]] => (apl: T[t], tt: t[A => B], ta: t[A]) => apl.ap(tt)(ta)) - override def map[A, B](fa: F[A])(f: A => B): F[B] = - inst.map(fa: F[A])([f[_]] => (tf: T[f], fa: f[A]) => tf.map(fa)(f)) + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedApply_F[F[_]: Or, G[_]: Or]: DerivedApply[[x] =>> F[G[x]]] = summon + + trait Product[T[f[_]] <: Apply[f], F[_]](using inst: K1.ProductInstances[T, F]) extends Apply[F]: + private lazy val F = new DerivedFunctor.Generic[T, F] {} + final override def map[A, B](fa: F[A])(f: A => B): F[B] = F.map(fa)(f) + final override def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] = + inst.map2(ff, fa)([f[_]] => (F: T[f], ff: f[A => B], fa: f[A]) => F.ap(ff)(fa)) diff --git a/core/src/main/scala-3/cats/derived/DerivedContravariant.scala b/core/src/main/scala-3/cats/derived/DerivedContravariant.scala index b3cec8e8..410012f9 100644 --- a/core/src/main/scala-3/cats/derived/DerivedContravariant.scala +++ b/core/src/main/scala-3/cats/derived/DerivedContravariant.scala @@ -1,6 +1,6 @@ package cats.derived -import cats.{Contravariant, Functor} +import cats.Contravariant import shapeless3.deriving.{Const, K1} import scala.annotation.implicitNotFound @@ -22,14 +22,18 @@ object DerivedContravariant: given [T]: DerivedContravariant[Const[T]] = new Contravariant[Const[T]]: def contramap[A, B](fa: T)(f: B => A): T = fa - given [F[_], G[_]](using F: DerivedFunctor.Or[F], G: Or[G]): DerivedContravariant[[x] =>> F[G[x]]] = - given Contravariant[G] = G.unify - F.unify.composeContravariant[G] + given nested[F[_], G[_]](using F: DerivedFunctor.Or[F], G: => Or[G]): DerivedContravariant[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.composeContravariant(G.unify)) with Contravariant[[x] =>> F[G[x]]]: + export delegate.* given [F[_]](using inst: => K1.Instances[Or, F]): DerivedContravariant[F] = given K1.Instances[Contravariant, F] = inst.unify new Generic[Contravariant, F] {} - trait Generic[T[x[_]] <: Contravariant[x], F[_]](using inst: K1.Instances[T, F]) extends Contravariant[F]: + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedContravariant_F[F[_]: DerivedFunctor.Or, G[_]: Or] + : DerivedContravariant[[x] =>> F[G[x]]] = summon + + trait Generic[T[f[_]] <: Contravariant[f], F[_]](using inst: K1.Instances[T, F]) extends Contravariant[F]: final override def contramap[A, B](fa: F[A])(f: B => A): F[B] = - inst.map(fa: F[A])([f[_]] => (tf: T[f], fa: f[A]) => tf.contramap(fa)(f)) + inst.map(fa)([f[_]] => (T: T[f], fa: f[A]) => T.contramap(fa)(f)) diff --git a/core/src/main/scala-3/cats/derived/DerivedEmptyK.scala b/core/src/main/scala-3/cats/derived/DerivedEmptyK.scala index 53d55adc..cef066ed 100644 --- a/core/src/main/scala-3/cats/derived/DerivedEmptyK.scala +++ b/core/src/main/scala-3/cats/derived/DerivedEmptyK.scala @@ -1,6 +1,6 @@ package cats.derived -import alleycats.{Empty, EmptyK, Pure} +import alleycats.{Empty, EmptyK} import shapeless3.deriving.{Const, K1} import scala.annotation.implicitNotFound @@ -21,21 +21,32 @@ object DerivedEmptyK: import DerivedEmptyK.given summonInline[DerivedEmptyK[F]].instance - given [T](using T: Empty[T]): DerivedEmptyK[Const[T]] = - new EmptyK[Const[T]]: - def empty[A] = T.empty + given [T](using T: Empty[T]): DerivedEmptyK[Const[T]] = new EmptyK[Const[T]]: + def empty[A]: T = T.empty - given [F[_], G[_]](using F: Or[F]): DerivedEmptyK[[x] =>> F[G[x]]] = - new EmptyK[[x] =>> F[G[x]]]: - def empty[A] = F.unify.empty + given nested[F[_], G[_]](using F: => Or[F]): DerivedEmptyK[[x] =>> F[G[x]]] = new EmptyK[[x] =>> F[G[x]]]: + lazy val f = F.unify + def empty[A]: F[G[A]] = f.empty - given [F[_], G[_]](using NotGiven[Or[F]])(using F: DerivedPure.Or[F], G: Or[G]): DerivedEmptyK[[x] =>> F[G[x]]] = - new EmptyK[[x] =>> F[G[x]]]: - def empty[A] = F.unify.pure(G.unify.empty) + given nested[F[_], G[_]](using NotGiven[Or[F]])(using + F: DerivedPure.Or[F], + G: => Or[G] + ): DerivedEmptyK[[x] =>> F[G[x]]] = new EmptyK[[x] =>> F[G[x]]]: + val f = F.unify + lazy val g = G.unify + def empty[A]: F[G[A]] = f.pure(g.empty) - given product[F[_]](using inst: K1.ProductInstances[Or, F]): DerivedEmptyK[F] = - new EmptyK[F]: - def empty[A]: F[A] = inst.unify.construct([f[_]] => (E: EmptyK[f]) => E.empty[A]) + given product[F[_]](using inst: K1.ProductInstances[Or, F]): DerivedEmptyK[F] = new EmptyK[F]: + val f = inst.unify + def empty[A]: F[A] = f.construct([f[_]] => (F: EmptyK[f]) => F.empty[A]) inline given coproduct[F[_]](using gen: K1.CoproductGeneric[F]): DerivedEmptyK[F] = - gen.withOnly[Or, EmptyK[F]]([f[x] <: F[x]] => (ek: Or[f]) => ek.unify.asInstanceOf[EmptyK[F]]) + gen.withOnly[Or, EmptyK[F]]([f[x] <: F[x]] => (F: Or[f]) => F.unify.asInstanceOf[EmptyK[F]]) + + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedEmptyK_F[F[_]: Or, G[_]]: DerivedEmptyK[[x] =>> F[G[x]]] = summon + + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedEmptyK_F[F[_]: DerivedPure.Or, G[_]: Or]( + ev: NotGiven[Or[F]] + ): DerivedEmptyK[[x] =>> F[G[x]]] = nested(using ev) diff --git a/core/src/main/scala-3/cats/derived/DerivedFoldable.scala b/core/src/main/scala-3/cats/derived/DerivedFoldable.scala index fc3a9de2..914d0557 100644 --- a/core/src/main/scala-3/cats/derived/DerivedFoldable.scala +++ b/core/src/main/scala-3/cats/derived/DerivedFoldable.scala @@ -23,8 +23,9 @@ object DerivedFoldable: def foldLeft[A, B](fa: T, b: B)(f: (B, A) => B): B = b def foldRight[A, B](fa: T, lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = lb - given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedFoldable[[x] =>> F[G[x]]] = - F.unify.compose(G.unify) + given nested[F[_], G[_]](using F: => Or[F], G: => Or[G]): DerivedFoldable[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.compose(G.unify)) with Foldable[[x] =>> F[G[x]]]: + export delegate.* given [F[_]](using inst: K1.ProductInstances[Or, F]): DerivedFoldable[F] = given K1.ProductInstances[Foldable, F] = inst.unify @@ -34,18 +35,20 @@ object DerivedFoldable: given K1.CoproductInstances[Foldable, F] = inst.unify new Coproduct[Foldable, F] {} - trait Product[T[x[_]] <: Foldable[x], F[_]](using inst: K1.ProductInstances[T, F]) extends Foldable[F]: + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedFoldable_F[F[_]: Or, G[_]: Or]: DerivedFoldable[[x] =>> F[G[x]]] = summon + + trait Product[T[f[_]] <: Foldable[f], F[_]](using inst: K1.ProductInstances[T, F]) extends Foldable[F]: final override def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B = - inst.foldLeft[A, B](fa)(b)([f[_]] => (acc: B, tf: T[f], fa: f[A]) => Continue(tf.foldLeft(fa, acc)(f))) + inst.foldLeft(fa)(b)([f[_]] => (b: B, F: T[f], fa: f[A]) => Continue(F.foldLeft(fa, b)(f))) final override def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = - inst.foldRight[A, Eval[B]](fa)(lb)( - [f[_]] => (tf: T[f], fa: f[A], acc: Eval[B]) => Continue(Eval.defer(tf.foldRight(fa, acc)(f))) - ) + inst.foldRight(fa)(lb): + [f[_]] => (F: T[f], fa: f[A], lb: Eval[B]) => Continue(Eval.defer(F.foldRight(fa, lb)(f))) - trait Coproduct[T[x[_]] <: Foldable[x], F[_]](using inst: K1.CoproductInstances[T, F]) extends Foldable[F]: + trait Coproduct[T[f[_]] <: Foldable[f], F[_]](using inst: K1.CoproductInstances[T, F]) extends Foldable[F]: final override def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B = - inst.fold[A, B](fa)([f[_]] => (tf: T[f], fa: f[A]) => tf.foldLeft(fa, b)(f)) + inst.fold(fa)([f[_]] => (F: T[f], fa: f[A]) => F.foldLeft(fa, b)(f)) final override def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = - inst.fold[A, Eval[B]](fa)([f[_]] => (tf: T[f], fa: f[A]) => Eval.defer(tf.foldRight(fa, lb)(f))) + inst.fold(fa)([f[_]] => (F: T[f], fa: f[A]) => Eval.defer(F.foldRight(fa, lb)(f))) diff --git a/core/src/main/scala-3/cats/derived/DerivedFunctor.scala b/core/src/main/scala-3/cats/derived/DerivedFunctor.scala index 07c0ecae..6fce4bad 100644 --- a/core/src/main/scala-3/cats/derived/DerivedFunctor.scala +++ b/core/src/main/scala-3/cats/derived/DerivedFunctor.scala @@ -1,6 +1,6 @@ package cats.derived -import cats.{Contravariant, Functor} +import cats.Functor import shapeless3.deriving.{Const, K1} import scala.annotation.implicitNotFound @@ -23,20 +23,30 @@ object DerivedFunctor: given [T]: DerivedFunctor[Const[T]] = new Functor[Const[T]]: def map[A, B](fa: T)(f: A => B): T = fa - given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedFunctor[[x] =>> F[G[x]]] = - F.unify.compose(G.unify) + given nested[F[_], G[_]](using F: => Or[F], G: => Or[G]): DerivedFunctor[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.compose(G.unify)) with Functor[[x] =>> F[G[x]]]: + export delegate.* - given [F[_], G[_]](using + given nested[F[_], G[_]](using F: DerivedContravariant.Or[F], G: DerivedContravariant.Or[G] ): DerivedFunctor[[x] =>> F[G[x]]] = - given Contravariant[G] = G.unify - F.unify.compose[G] + F.unify.compose(G.unify) given [F[_]](using inst: => K1.Instances[Or, F]): DerivedFunctor[F] = given K1.Instances[Functor, F] = inst.unify new Generic[Functor, F] {} - trait Generic[T[x[_]] <: Functor[x], F[_]](using inst: K1.Instances[T, F]) extends Functor[F]: + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedFunctor_F[F[_], G[_]](using F: Or[F], G: Or[G]): DerivedFunctor[[x] =>> F[G[x]]] = + nested(using F, G) + + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedFunctor_F[F[_], G[_]](using + F: DerivedContravariant.Or[F], + G: DerivedContravariant.Or[G] + ): DerivedFunctor[[x] =>> F[G[x]]] = nested(using F, G) + + trait Generic[T[f[_]] <: Functor[f], F[_]](using inst: K1.Instances[T, F]) extends Functor[F]: final override def map[A, B](fa: F[A])(f: A => B): F[B] = - inst.map(fa: F[A])([f[_]] => (tf: T[f], fa: f[A]) => tf.map(fa)(f)) + inst.map(fa)([f[_]] => (F: T[f], fa: f[A]) => F.map(fa)(f)) diff --git a/core/src/main/scala-3/cats/derived/DerivedInvariant.scala b/core/src/main/scala-3/cats/derived/DerivedInvariant.scala index 41b1be98..dfce8549 100644 --- a/core/src/main/scala-3/cats/derived/DerivedInvariant.scala +++ b/core/src/main/scala-3/cats/derived/DerivedInvariant.scala @@ -1,11 +1,10 @@ package cats.derived -import cats.{Contravariant, Functor, Invariant} +import cats.Invariant import shapeless3.deriving.{Const, K1} import scala.annotation.implicitNotFound import scala.compiletime.* -import scala.util.NotGiven @implicitNotFound("""Could not derive an instance of Invariant[F] where F = ${F}. Make sure that F[_] satisfies one of the following conditions: @@ -23,15 +22,17 @@ object DerivedInvariant: given [T]: DerivedInvariant[Const[T]] = new Invariant[Const[T]]: def imap[A, B](fa: T)(f: A => B)(g: B => A): T = fa - given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedInvariant[[x] =>> F[G[x]]] = - given Invariant[G] = G.unify - F.unify.compose[G] + given nested[F[_], G[_]](using F: => Or[F], G: => Or[G]): DerivedInvariant[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.compose(G.unify)) with Invariant[[x] =>> F[G[x]]]: + export delegate.* given [F[_]](using inst: => K1.Instances[Or, F]): DerivedInvariant[F] = given K1.Instances[Invariant, F] = inst.unify new Generic[Invariant, F] {} - trait Generic[T[x[_]] <: Invariant[x], F[_]](using inst: K1.Instances[T, F]) extends Invariant[F]: - def imap[A, B](fa: F[A])(f: A => B)(g: B => A): F[B] = inst.map(fa)( - [t[_]] => (inv: T[t], t0: t[A]) => inv.imap(t0)(f)(g) - ) + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedInvariant_F[F[_]: Or, G[_]: Or]: DerivedInvariant[[x] =>> F[G[x]]] = summon + + trait Generic[T[f[_]] <: Invariant[f], F[_]](using inst: K1.Instances[T, F]) extends Invariant[F]: + final override def imap[A, B](fa: F[A])(f: A => B)(g: B => A): F[B] = + inst.map(fa)([f[_]] => (F: T[f], fa: f[A]) => F.imap(fa)(f)(g)) diff --git a/core/src/main/scala-3/cats/derived/DerivedMonoidK.scala b/core/src/main/scala-3/cats/derived/DerivedMonoidK.scala index 69cc75d0..dad39ac9 100644 --- a/core/src/main/scala-3/cats/derived/DerivedMonoidK.scala +++ b/core/src/main/scala-3/cats/derived/DerivedMonoidK.scala @@ -21,31 +21,35 @@ object DerivedMonoidK: summonInline[DerivedMonoidK[F]].instance given [T](using T: Monoid[T]): DerivedMonoidK[Const[T]] = new MonoidK[Const[T]]: - final override def empty[A]: Const[T][A] = T.empty - - final override def combineK[A](x: Const[T][A], y: Const[T][A]) = T.combine(x, y) - - given [F[_], G[_]](using F: Or[F]): DerivedMonoidK[[x] =>> F[G[x]]] = - F.unify.compose[G] - - given [F[_], G[_]](using - N: NotGiven[Or[F]], - F0: DerivedApplicative.Or[F], - G0: Or[G] - ): DerivedMonoidK[[x] =>> F[G[x]]] = - new MonoidK[[x] =>> F[G[x]]]: - val F: Applicative[F] = F0.unify - val G: MonoidK[G] = G0.unify - - final override def empty[A]: F[G[A]] = F.pure(G.empty[A]) - - final override def combineK[A](x: F[G[A]], y: F[G[A]]): F[G[A]] = F.map2(x, y)(G.combineK(_, _)) + def empty[A]: T = T.empty + def combineK[A](x: T, y: T): T = T.combine(x, y) + + given nested[F[_], G[_]](using F: => Or[F]): DerivedMonoidK[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.compose[G]) with MonoidK[[x] =>> F[G[x]]]: + export delegate.* + + given nested[F[_], G[_]](using NotGiven[Or[F]])(using + F: DerivedApplicative.Or[F], + G: => Or[G] + ): DerivedMonoidK[[x] =>> F[G[x]]] = new MonoidK[[x] =>> F[G[x]]]: + val f: Applicative[F] = F.unify + lazy val g: MonoidK[G] = G.unify + def empty[A]: F[G[A]] = f.pure(g.empty[A]) + def combineK[A](x: F[G[A]], y: F[G[A]]): F[G[A]] = f.map2(x, y)(g.combineK) given [F[_]](using inst: => K1.ProductInstances[Or, F]): DerivedMonoidK[F] = given K1.ProductInstances[MonoidK, F] = inst.unify new Product[MonoidK, F] {} - trait Product[T[x[_]] <: MonoidK[x], F[_]](using inst: K1.ProductInstances[T, F]) + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedMonoidK_F[F[_]: Or, G[_]]: DerivedMonoidK[[x] =>> F[G[x]]] = summon + + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedMonoidK_F[F[_]: DerivedApplicative.Or, G[_]: Or]( + ev: NotGiven[Or[F]] + ): DerivedMonoidK[[x] =>> F[G[x]]] = nested(using ev) + + trait Product[T[f[_]] <: MonoidK[f], F[_]](using inst: K1.ProductInstances[T, F]) extends MonoidK[F], DerivedSemigroupK.Product[T, F]: - final override def empty[A]: F[A] = inst.construct([t[_]] => (emp: T[t]) => emp.empty[A]) + final override def empty[A]: F[A] = inst.construct([f[_]] => (F: T[f]) => F.empty[A]) diff --git a/core/src/main/scala-3/cats/derived/DerivedNonEmptyTraverse.scala b/core/src/main/scala-3/cats/derived/DerivedNonEmptyTraverse.scala index c13e305b..90a44ee2 100644 --- a/core/src/main/scala-3/cats/derived/DerivedNonEmptyTraverse.scala +++ b/core/src/main/scala-3/cats/derived/DerivedNonEmptyTraverse.scala @@ -1,7 +1,7 @@ package cats.derived -import cats.{Applicative, Apply, NonEmptyTraverse, Traverse} -import shapeless3.deriving.{Const, K1} +import cats.{Applicative, Apply, Eval, NonEmptyTraverse, Traverse} +import shapeless3.deriving.K1 import scala.annotation.implicitNotFound import scala.compiletime.* @@ -19,8 +19,9 @@ object DerivedNonEmptyTraverse: import DerivedNonEmptyTraverse.given summonInline[DerivedNonEmptyTraverse[F]].instance - given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedNonEmptyTraverse[[x] =>> F[G[x]]] = - F.unify.compose(G.unify) + given nested[F[_], G[_]](using F: => Or[F], G: => Or[G]): DerivedNonEmptyTraverse[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.compose(G.unify)) with NonEmptyTraverse[[x] =>> F[G[x]]]: + export delegate.* def product[F[_]](ev: NonEmptyTraverse[?])(using inst: K1.ProductInstances[DerivedTraverse.Or, F] @@ -41,6 +42,10 @@ object DerivedNonEmptyTraverse: with DerivedTraverse.Coproduct[NonEmptyTraverse, F] with DerivedFunctor.Generic[NonEmptyTraverse, F] {} + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedNonEmptyTraverse_F[F[_]: Or, G[_]: Or]: DerivedNonEmptyTraverse[[x] =>> F[G[x]]] = + summon + trait Product[T[x[_]] <: Traverse[x], F[_]](ev: NonEmptyTraverse[?])(using inst: K1.ProductInstances[T, F] ) extends NonEmptyTraverse[F], @@ -59,7 +64,7 @@ object DerivedNonEmptyTraverse: DerivedTraverse.Coproduct[T, F]: final override def nonEmptyTraverse[G[_]: Apply, A, B](fa: F[A])(f: A => G[B]): G[F[B]] = - inst.fold(fa)([f[_]] => (tf: T[f], fa: f[A]) => tf.nonEmptyTraverse(fa)(f).asInstanceOf[G[F[B]]]) + inst.fold(fa)([f[_]] => (F: T[f], fa: f[A]) => F.nonEmptyTraverse(fa)(f).asInstanceOf[G[F[B]]]) private type Alt[F[_]] = [A] =>> Either[F[A], A] private given [F[_]](using F: Apply[F]): Applicative[Alt[F]] with diff --git a/core/src/main/scala-3/cats/derived/DerivedPure.scala b/core/src/main/scala-3/cats/derived/DerivedPure.scala index 666dd32f..8e8caaa2 100644 --- a/core/src/main/scala-3/cats/derived/DerivedPure.scala +++ b/core/src/main/scala-3/cats/derived/DerivedPure.scala @@ -12,25 +12,26 @@ Make sure that F[_] satisfies one of the following conditions: * it is a nested type [x] =>> G[H[x]] where G: Pure and H: Pure * it is a generic case class where all fields have a Pure instance""") type DerivedPure[F[_]] = Derived[Pure[F]] - object DerivedPure: type Or[F[_]] = Derived.Or[Pure[F]] inline def apply[F[_]]: Pure[F] = import DerivedPure.given summonInline[DerivedPure[F]].instance - given [T](using T: Empty[T]): DerivedPure[Const[T]] = - new Pure[Const[T]]: - def pure[A](a: A) = T.empty + given [T](using T: Empty[T]): DerivedPure[Const[T]] = new Pure[Const[T]]: + def pure[A](a: A): T = T.empty + + given [T <: Singleton: ValueOf]: DerivedPure[Const[T]] = new Pure[Const[T]]: + def pure[A](a: A): T = valueOf[T] - given [T <: Singleton: ValueOf]: DerivedPure[Const[T]] = - new Pure[Const[T]]: - def pure[A](a: A) = valueOf[T] + given nested[F[_], G[_]](using F: => Or[F], G: => Or[G]): DerivedPure[[x] =>> F[G[x]]] = new Pure[[x] =>> F[G[x]]]: + lazy val f = F.unify + lazy val g = G.unify + def pure[A](a: A): F[G[A]] = f.pure(g.pure(a)) - given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedPure[[x] =>> F[G[x]]] = - new Pure[[x] =>> F[G[x]]]: - def pure[A](a: A) = F.unify.pure(G.unify.pure(a)) + given [F[_]](using inst: K1.ProductInstances[Or, F]): DerivedPure[F] = new Pure[F]: + val f = inst.unify + def pure[A](a: A): F[A] = f.construct([f[_]] => (F: Pure[f]) => F.pure(a)) - given [F[_]](using inst: K1.ProductInstances[Or, F]): DerivedPure[F] = - new Pure[F]: - def pure[A](a: A) = inst.unify.construct([f[_]] => (P: Pure[f]) => P.pure(a)) + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedPure_F[F[_]: Or, G[_]: Or]: DerivedPure[[x] =>> F[G[x]]] = summon diff --git a/core/src/main/scala-3/cats/derived/DerivedReducible.scala b/core/src/main/scala-3/cats/derived/DerivedReducible.scala index e6dfdea1..f7f8ec52 100644 --- a/core/src/main/scala-3/cats/derived/DerivedReducible.scala +++ b/core/src/main/scala-3/cats/derived/DerivedReducible.scala @@ -19,8 +19,9 @@ object DerivedReducible: import DerivedReducible.given summonInline[DerivedReducible[F]].instance - given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedReducible[[x] =>> F[G[x]]] = - F.unify.compose(G.unify) + given nested[F[_], G[_]](using F: => Or[F], G: => Or[G]): DerivedReducible[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.compose(G.unify)) with Reducible[[x] =>> F[G[x]]]: + export delegate.* def product[F[_]](ev: Reducible[?])(using inst: K1.ProductInstances[DerivedFoldable.Or, F]): DerivedReducible[F] = given K1.ProductInstances[Foldable, F] = inst.unify @@ -33,7 +34,10 @@ object DerivedReducible: given K1.CoproductInstances[Reducible, F] = inst.unify new Coproduct[Reducible, F] {} - trait Product[T[x[_]] <: Foldable[x], F[_]](ev: Reducible[?])(using inst: K1.ProductInstances[T, F]) + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedReducible_F[F[_]: Or, G[_]: Or]: DerivedReducible[[x] =>> F[G[x]]] = summon + + trait Product[T[f[_]] <: Foldable[f], F[_]](ev: Reducible[?])(using inst: K1.ProductInstances[T, F]) extends DerivedFoldable.Product[T, F], Reducible[F]: @@ -41,33 +45,31 @@ object DerivedReducible: final override def reduceLeftTo[A, B](fa: F[A])(f: A => B)(g: (B, A) => B): B = inst - .foldLeft[A, Option[B]](fa)(None)( + .foldLeft[A, Option[B]](fa)(None): [f[_]] => - (acc: Option[B], tf: T[f], fa: f[A]) => + (acc: Option[B], F: T[f], fa: f[A]) => acc match - case Some(b) => Continue(Some(tf.foldLeft(fa, b)(g))) - case None => Continue(tf.reduceLeftToOption(fa)(f)(g)) - ) + case Some(b) => Continue(Some(F.foldLeft(fa, b)(g))) + case None => Continue(F.reduceLeftToOption(fa)(f)(g)) .get final override def reduceRightTo[A, B](fa: F[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = inst - .foldRight[A, Eval[Option[B]]](fa)(evalNone)( + .foldRight[A, Eval[Option[B]]](fa)(evalNone): [f[_]] => - (tf: T[f], fa: f[A], acc: Eval[Option[B]]) => + (F: T[f], fa: f[A], acc: Eval[Option[B]]) => Continue(acc.flatMap { - case Some(b) => tf.foldRight(fa, Eval.now(b))(g).map(Some.apply) - case None => tf.reduceRightToOption(fa)(f)(g) + case Some(b) => F.foldRight(fa, Eval.now(b))(g).map(Some.apply) + case None => F.reduceRightToOption(fa)(f)(g) }) - ) .map(_.get) - trait Coproduct[T[x[_]] <: Reducible[x], F[_]](using inst: K1.CoproductInstances[T, F]) + trait Coproduct[T[f[_]] <: Reducible[f], F[_]](using inst: K1.CoproductInstances[T, F]) extends DerivedFoldable.Coproduct[T, F], Reducible[F]: final override def reduceLeftTo[A, B](fa: F[A])(f: A => B)(g: (B, A) => B): B = - inst.fold[A, B](fa)([f[_]] => (tf: T[f], fa: f[A]) => tf.reduceLeftTo(fa)(f)(g)) + inst.fold(fa)([f[_]] => (F: T[f], fa: f[A]) => F.reduceLeftTo(fa)(f)(g)) final override def reduceRightTo[A, B](fa: F[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = - inst.fold[A, Eval[B]](fa)([f[_]] => (tf: T[f], fa: f[A]) => Eval.defer(tf.reduceRightTo(fa)(f)(g))) + inst.fold(fa)([f[_]] => (F: T[f], fa: f[A]) => Eval.defer(F.reduceRightTo(fa)(f)(g))) diff --git a/core/src/main/scala-3/cats/derived/DerivedSemigroupK.scala b/core/src/main/scala-3/cats/derived/DerivedSemigroupK.scala index d3099cfb..2bf0f576 100644 --- a/core/src/main/scala-3/cats/derived/DerivedSemigroupK.scala +++ b/core/src/main/scala-3/cats/derived/DerivedSemigroupK.scala @@ -21,19 +21,32 @@ object DerivedSemigroupK: summonInline[DerivedSemigroupK[F]].instance given [T](using T: Semigroup[T]): DerivedSemigroupK[Const[T]] = new SemigroupK[Const[T]]: - final override def combineK[A](x: Const[T][A], y: Const[T][A]) = T.combine(x, y) + def combineK[A](x: T, y: T): T = T.combine(x, y) - given [F[_], G[_]](using F: Or[F]): DerivedSemigroupK[[x] =>> F[G[x]]] = - F.unify.compose[G] + given nested[F[_], G[_]](using F: => Or[F]): DerivedSemigroupK[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.compose[G]) with SemigroupK[[x] =>> F[G[x]]]: + export delegate.* - given [F[_], G[_]](using N: NotGiven[Or[F]], F: DerivedApply.Or[F], G: Or[G]): DerivedSemigroupK[[x] =>> F[G[x]]] = - new SemigroupK[[x] =>> F[G[x]]]: - final override def combineK[A](x: F[G[A]], y: F[G[A]]): F[G[A]] = F.unify.map2(x, y)(G.unify.combineK(_, _)) + given nested[F[_], G[_]](using NotGiven[Or[F]])(using + F: DerivedApply.Or[F], + G: => Or[G] + ): DerivedSemigroupK[[x] =>> F[G[x]]] = new SemigroupK[[x] =>> F[G[x]]]: + val f = F.unify + lazy val g = G.unify + def combineK[A](x: F[G[A]], y: F[G[A]]): F[G[A]] = f.map2(x, y)(g.combineK) given [F[_]](using inst: => K1.ProductInstances[Or, F]): DerivedSemigroupK[F] = given K1.ProductInstances[SemigroupK, F] = inst.unify new Product[SemigroupK, F] {} - trait Product[T[x[_]] <: SemigroupK[x], F[_]](using inst: K1.ProductInstances[T, F]) extends SemigroupK[F]: + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedSemigroupK_F[F[_]: Or, G[_]]: DerivedSemigroupK[[x] =>> F[G[x]]] = summon + + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedSemigroupK_F[F[_]: DerivedApply.Or, G[_]: Or]( + ev: NotGiven[Or[F]] + ): DerivedSemigroupK[[x] =>> F[G[x]]] = nested(using ev) + + trait Product[T[f[_]] <: SemigroupK[f], F[_]](using inst: K1.ProductInstances[T, F]) extends SemigroupK[F]: final override def combineK[A](x: F[A], y: F[A]): F[A] = - inst.map2[A, A, A](x, y)([t[_]] => (smgrpk: T[t], x: t[A], y: t[A]) => smgrpk.combineK(x, y)) + inst.map2(x, y)([f[_]] => (F: T[f], x: f[A], y: f[A]) => F.combineK(x, y)) diff --git a/core/src/main/scala-3/cats/derived/DerivedTraverse.scala b/core/src/main/scala-3/cats/derived/DerivedTraverse.scala index 3467b88f..f873c65a 100644 --- a/core/src/main/scala-3/cats/derived/DerivedTraverse.scala +++ b/core/src/main/scala-3/cats/derived/DerivedTraverse.scala @@ -25,8 +25,9 @@ object DerivedTraverse: override def foldRight[A, B](fa: T, lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = lb override def traverse[G[_], A, B](fa: T)(f: A => G[B])(using G: Applicative[G]): G[T] = G.pure(fa) - given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedTraverse[[x] =>> F[G[x]]] = - F.unify.compose(G.unify) + given nested[F[_], G[_]](using F: => Or[F], G: => Or[G]): DerivedTraverse[[x] =>> F[G[x]]] = + new Derived.Lazy(() => F.unify.compose(G.unify)) with Traverse[[x] =>> F[G[x]]]: + export delegate.* given [F[_]](using inst: K1.ProductInstances[Or, F]): DerivedTraverse[F] = given K1.ProductInstances[Traverse, F] = inst.unify @@ -36,7 +37,10 @@ object DerivedTraverse: given K1.CoproductInstances[Traverse, F] = inst.unify new Coproduct[Traverse, F] with DerivedFunctor.Generic[Traverse, F] {} - trait Product[T[x[_]] <: Traverse[x], F[_]](using inst: K1.ProductInstances[T, F]) + @deprecated("Kept for binary compatibility", "3.2.0") + private[derived] def given_DerivedTraverse_F[F[_]: Or, G[_]: Or]: DerivedTraverse[[x] =>> F[G[x]]] = summon + + trait Product[T[f[_]] <: Traverse[f], F[_]](using inst: K1.ProductInstances[T, F]) extends Traverse[F], DerivedFunctor.Generic[T, F], DerivedFoldable.Product[T, F]: @@ -45,12 +49,12 @@ object DerivedTraverse: val pure = [a] => (x: a) => G.pure(x) val map = [a, b] => (ga: G[a], f: a => b) => G.map(ga)(f) val ap = [a, b] => (gf: G[a => b], ga: G[a]) => G.ap(gf)(ga) - inst.traverse[A, G, B](fa)(map)(pure)(ap)([f[_]] => (tf: T[f], fa: f[A]) => tf.traverse(fa)(f)) + inst.traverse[A, G, B](fa)(map)(pure)(ap)([f[_]] => (F: T[f], fa: f[A]) => F.traverse(fa)(f)) - trait Coproduct[T[x[_]] <: Traverse[x], F[_]](using inst: K1.CoproductInstances[T, F]) + trait Coproduct[T[f[_]] <: Traverse[f], F[_]](using inst: K1.CoproductInstances[T, F]) extends Traverse[F], DerivedFunctor.Generic[T, F], DerivedFoldable.Coproduct[T, F]: final override def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]] = - inst.fold(fa)([f[_]] => (tf: T[f], fa: f[A]) => tf.traverse(fa)(f).asInstanceOf[G[F[B]]]) + inst.fold(fa)([f[_]] => (F: T[f], fa: f[A]) => F.traverse(fa)(f).asInstanceOf[G[F[B]]]) diff --git a/core/src/test/scala-3/cats/derived/ADTs.scala b/core/src/test/scala-3/cats/derived/ADTs.scala index 653cfa0a..53f3c1ed 100644 --- a/core/src/test/scala-3/cats/derived/ADTs.scala +++ b/core/src/test/scala-3/cats/derived/ADTs.scala @@ -272,6 +272,15 @@ object ADTs: ) ) + final case class Search[+A](move: A, child: Option[Search[A]], variations: List[Search[A]]) + object Search: + given [A: Arbitrary]: Arbitrary[Search[A]] = Arbitrary(Gen.sized: n => + for + move <- Arbitrary.arbitrary[A] + child <- Gen.resize(n / 2, Arbitrary.arbitrary[Option[Search[A]]]) + variations <- Gen.resize(n / 2, Arbitrary.arbitrary[List[Search[A]]]) + yield Search(move, child, variations)) + trait EqInstances: import ADTs.* @@ -322,5 +331,8 @@ object ADTs: case (EnumK1Inv.Rec(l1, r1), EnumK1Inv.Rec(l2, r2)) => l1 === l2 && r1 === r2 case _ => false + given [A: Eq]: Eq[Search[A]] = + (x, y) => x.move === y.move && x.child === y.child && x.variations === y.variations + end EqInstances end ADTs diff --git a/core/src/test/scala-3/cats/derived/ApplySuite.scala b/core/src/test/scala-3/cats/derived/ApplySuite.scala index bb066b65..2c958856 100644 --- a/core/src/test/scala-3/cats/derived/ApplySuite.scala +++ b/core/src/test/scala-3/cats/derived/ApplySuite.scala @@ -37,26 +37,24 @@ class ApplySuite extends KittensSuite: checkAll(s"$instance[AndInt]", tests[AndInt].apply[Int, String, Long]) checkAll(s"$instance[Interleaved]", tests[Interleaved].apply[Int, String, Long]) checkAll(s"$instance[ListBox]", tests[ListBox].apply[Int, String, Long]) + checkAll(s"$instance[Search]", tests[Search].apply[Int, String, Long]) checkAll(s"$instance is Serializable", SerializableTests.serializable(summonInline[Apply[Interleaved]])) - locally { + locally: import auto.apply.given validate("auto.apply") - } - locally { + locally: import semiInstances.given validate("semiauto.apply") - } - locally { + locally: import derivedInstances.* val instance = "derived.apply" checkAll(s"$instance[CaseClassWOption]", tests[CaseClassWOption].apply[Int, String, Long]) checkAll(s"$instance[AndInt]", tests[AndInt].apply[Int, String, Long]) checkAll(s"$instance[Interleaved]", tests[Interleaved].apply[Int, String, Long]) checkAll(s"$instance is Serializable", SerializableTests.serializable(Apply[Interleaved])) - } end ApplySuite @@ -74,6 +72,7 @@ object ApplySuite: given Apply[AndInt] = semiauto.apply given Apply[Interleaved] = semiauto.apply given Apply[ListBox] = semiauto.apply + given Apply[Search] = semiauto.apply object derivedInstances: case class CaseClassWOption[A](x: ADTs.CaseClassWOption[A]) derives Apply diff --git a/core/src/test/scala-3/cats/derived/FoldableSuite.scala b/core/src/test/scala-3/cats/derived/FoldableSuite.scala index b4fd85d7..303ae89b 100644 --- a/core/src/test/scala-3/cats/derived/FoldableSuite.scala +++ b/core/src/test/scala-3/cats/derived/FoldableSuite.scala @@ -42,6 +42,7 @@ class FoldableSuite extends KittensSuite: checkAll(s"$instance[AtMostOne]", tests[AtMostOne].foldable[Int, Long]) checkAll(s"$instance[AtLeastOne]", tests[AtLeastOne].foldable[Int, Long]) checkAll(s"$instance[Singletons]", tests[Singletons].foldable[Int, Long]) + checkAll(s"$instance[Search]", tests[Search].foldable[Int, Long]) checkAll(s"$instance is Serializable", SerializableTests.serializable(summonInline[Foldable[Tree]])) locally: @@ -91,6 +92,7 @@ object FoldableSuite: given Foldable[AtMostOne] = semiauto.foldable given Foldable[AtLeastOne] = semiauto.foldable given Foldable[Singletons] = semiauto.foldable + given Foldable[Search] = semiauto.foldable object derivedInstances: case class IList[A](x: ADTs.IList[A]) derives Foldable diff --git a/core/src/test/scala-3/cats/derived/FunctorSuite.scala b/core/src/test/scala-3/cats/derived/FunctorSuite.scala index f588446e..650a1326 100644 --- a/core/src/test/scala-3/cats/derived/FunctorSuite.scala +++ b/core/src/test/scala-3/cats/derived/FunctorSuite.scala @@ -45,6 +45,7 @@ class FunctorSuite extends KittensSuite: checkAll(s"$instance[AtMostOne]", tests[AtMostOne].functor[Boolean, Int, Boolean]) checkAll(s"$instance[AtLeastOne]", tests[AtLeastOne].functor[Boolean, Int, Boolean]) checkAll(s"$instance[Singletons]", tests[Singletons].functor[Boolean, Int, Boolean]) + checkAll(s"$instance[Search]", tests[Search].functor[Boolean, Int, Boolean]) checkAll(s"$instance is Serializable", SerializableTests.serializable(summonInline[Functor[Tree]])) locally: @@ -95,6 +96,7 @@ object FunctorSuite: given Functor[AtMostOne] = semiauto.functor given Functor[AtLeastOne] = semiauto.functor given Functor[Singletons] = semiauto.functor + given Functor[Search] = semiauto.functor object derivedInstances: case class IList[A](x: ADTs.IList[A]) derives Functor diff --git a/core/src/test/scala-3/cats/derived/InvariantSuite.scala b/core/src/test/scala-3/cats/derived/InvariantSuite.scala index 10f7bb9d..56da5cae 100644 --- a/core/src/test/scala-3/cats/derived/InvariantSuite.scala +++ b/core/src/test/scala-3/cats/derived/InvariantSuite.scala @@ -43,6 +43,7 @@ class InvariantSuite extends KittensSuite: checkAll(s"$instance[AtLeastOne]", tests[AtLeastOne].invariant[MiniInt, String, Boolean]) checkAll(s"$instance[AtMostOne]", tests[AtMostOne].invariant[MiniInt, String, Boolean]) checkAll(s"$instance[Singletons]", tests[Singletons].invariant[MiniInt, String, Boolean]) + checkAll(s"$instance[Search]", tests[Search].invariant[MiniInt, String, Boolean]) checkAll(s"$instance is Serializable", SerializableTests.serializable(summonInline[Invariant[TreeF]])) locally: @@ -93,6 +94,7 @@ object InvariantSuite: given Invariant[AtMostOne] = semiauto.invariant given Invariant[AtLeastOne] = semiauto.invariant given Invariant[Singletons] = semiauto.invariant + given Invariant[Search] = semiauto.invariant object derivedInstances: case class Bivariant[A](x: ADTs.Bivariant[A]) derives Invariant diff --git a/core/src/test/scala-3/cats/derived/NonEmptyTraverseSuite.scala b/core/src/test/scala-3/cats/derived/NonEmptyTraverseSuite.scala index 194c270e..dafa0c06 100644 --- a/core/src/test/scala-3/cats/derived/NonEmptyTraverseSuite.scala +++ b/core/src/test/scala-3/cats/derived/NonEmptyTraverseSuite.scala @@ -65,6 +65,10 @@ class NonEmptyTraverseSuite extends KittensSuite: s"$instance[Singletons]", tests[Singletons].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option] ) + checkAll( + s"$instance[Search]", + tests[Search].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option] + ) checkAll( s"$instance is Serializable", SerializableTests.serializable(summonInline[NonEmptyTraverse[Tree]]) @@ -126,6 +130,7 @@ object NonEmptyTraverseSuite: given NonEmptyTraverse[EnumK1] = semiauto.nonEmptyTraverse given NonEmptyTraverse[AtLeastOne] = semiauto.nonEmptyTraverse given NonEmptyTraverse[Singletons] = semiauto.nonEmptyTraverse + given NonEmptyTraverse[Search] = semiauto.nonEmptyTraverse object derivedInstances: case class ICons[A](x: ADTs.ICons[A]) derives NonEmptyTraverse diff --git a/core/src/test/scala-3/cats/derived/ReducibleSuite.scala b/core/src/test/scala-3/cats/derived/ReducibleSuite.scala index ea79ecb7..196778f4 100644 --- a/core/src/test/scala-3/cats/derived/ReducibleSuite.scala +++ b/core/src/test/scala-3/cats/derived/ReducibleSuite.scala @@ -40,6 +40,7 @@ class ReducibleSuite extends KittensSuite: checkAll(s"$instance[EnumK1]", tests[EnumK1].reducible[Option, Int, Long]) checkAll(s"$instance[AtLeastOne]", tests[AtLeastOne].reducible[Option, Int, Long]) checkAll(s"$instance[Singletons]", tests[Singletons].reducible[Option, Int, Long]) + checkAll(s"$instance[Search]", tests[Search].reducible[Option, Int, Long]) checkAll(s"$instance is Serializable", SerializableTests.serializable(summonInline[Reducible[Tree]])) locally: @@ -82,6 +83,7 @@ object ReducibleSuite: given Reducible[EnumK1] = semiauto.reducible given Reducible[AtLeastOne] = semiauto.reducible given Reducible[Singletons] = semiauto.reducible + given Reducible[Search] = semiauto.reducible object derivedInstances: case class ICons[A](x: ADTs.ICons[A]) derives Reducible diff --git a/core/src/test/scala-3/cats/derived/TraverseSuite.scala b/core/src/test/scala-3/cats/derived/TraverseSuite.scala index 3bdfd307..9bf28a0b 100644 --- a/core/src/test/scala-3/cats/derived/TraverseSuite.scala +++ b/core/src/test/scala-3/cats/derived/TraverseSuite.scala @@ -24,6 +24,7 @@ class TraverseSuite extends KittensSuite: checkAll(s"$instance[AtMostOne]", tests[AtMostOne].traverse[Int, Double, String, Long, Option, Option]) checkAll(s"$instance[AtLeastOne]", tests[AtLeastOne].traverse[Int, Double, String, Long, Option, Option]) checkAll(s"$instance[Singletons]", tests[Singletons].traverse[Int, Double, String, Long, Option, Option]) + checkAll(s"$instance[Search]", tests[Search].traverse[Int, Double, String, Long, Option, Option]) checkAll(s"$instance is Serializable", SerializableTests.serializable(summonInline[Traverse[Tree]])) locally: @@ -70,6 +71,7 @@ object TraverseSuite: given Traverse[AtLeastOne] = semiauto.traverse given Traverse[AtMostOne] = semiauto.traverse given Traverse[Singletons] = semiauto.traverse + given Traverse[Search] = semiauto.traverse object derivedInstances: case class IList[A](x: ADTs.IList[A]) derives Traverse