From 3863744a43841841a24496a026e7ddd79ec70acd Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Thu, 3 Jun 2021 02:26:39 +0300 Subject: [PATCH 1/7] Opaque invariant OrElse --- .../main/scala-3/cats/derived/functor.scala | 25 ++++++++----------- .../main/scala-3/cats/derived/orelse.scala | 19 ++++++++++++++ .../scala-3/cats/derived/ReducibleTests.scala | 1 + 3 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 core/src/main/scala-3/cats/derived/orelse.scala diff --git a/core/src/main/scala-3/cats/derived/functor.scala b/core/src/main/scala-3/cats/derived/functor.scala index b87f0051..f6dc718d 100644 --- a/core/src/main/scala-3/cats/derived/functor.scala +++ b/core/src/main/scala-3/cats/derived/functor.scala @@ -7,18 +7,21 @@ import scala.annotation.threadUnsafe object functor extends FunctorDerivation, Instances trait DerivedFunctor[F[_]] extends Functor[F] -object DerivedFunctor extends DerivedFunctorLowPriority: +object DerivedFunctor: + type Of[F[_]] = Functor[F] OrElse DerivedFunctor[F] + given const[T]: DerivedFunctor[Const[T]] with def map[A, B](fa: T)(f: A => B): T = fa - given delegated[F[_]](using F: => Functor[F]): DerivedFunctor[F] = - new Delegated(F) + given composed[F[_], G[_]](using F: Of[F], G: Of[G]): DerivedFunctor[[x] =>> F[G[x]]] with + private val underlying = F.unify `compose` G.unify + export underlying._ - given composed[F[_]: DerivedFunctor, G[_]: DerivedFunctor]: DerivedFunctor[[x] =>> F[G[x]]] = - new Delegated(Functor[F].compose[G]) + inline given derived[F[_]](using K1.Generic[F]): DerivedFunctor[F] = + generic - def generic[F[_]](using K1.Instances[DerivedFunctor, F]): DerivedFunctor[F] = - new Generic[DerivedFunctor, F] {} + def generic[F[_]](using inst: K1.Instances[Of, F]): DerivedFunctor[F] = + new Generic[Functor, F](using inst.unify) {} trait Generic[T[x[_]] <: Functor[x], F[_]](using inst: K1.Instances[T, F]) extends DerivedFunctor[F]: @@ -28,14 +31,6 @@ object DerivedFunctor extends DerivedFunctorLowPriority: tf.map(fa)(f) } - private final class Delegated[F[_]](F: => Functor[F]) extends DerivedFunctor[F]: - @threadUnsafe private lazy val underlying = F - export underlying._ - -private[derived] sealed abstract class DerivedFunctorLowPriority: - inline given derived[F[_]](using K1.Generic[F]): DerivedFunctor[F] = - DerivedFunctor.generic - trait FunctorDerivation: extension (F: Functor.type) def derived[F[_]](using instance: DerivedFunctor[F]): Functor[F] = instance diff --git a/core/src/main/scala-3/cats/derived/orelse.scala b/core/src/main/scala-3/cats/derived/orelse.scala new file mode 100644 index 00000000..af390e72 --- /dev/null +++ b/core/src/main/scala-3/cats/derived/orelse.scala @@ -0,0 +1,19 @@ +package cats.derived + +import shapeless3.deriving.K1 +import scala.compiletime._ + +opaque type OrElse[A, B] = A | B +object OrElse extends OrElseInstances: + def primary[A, B](a: A): A OrElse B = a + def secondary[A, B](b: => B): A OrElse B = b + extension [A, B](or: A OrElse B) + def unify: A | B = or + extension [A[_[_]], B[x[_]] <: A[x], F[_]](inst: K1.Instances[[x[_]] =>> A[x] OrElse B[x], F]) + def unify: K1.Instances[A, F] = inst + +private[derived] sealed abstract class OrElseInstances: + inline given [A, B]: OrElse[A, B] = summonFrom { + case a: A => OrElse.primary(a) + case b: B => OrElse.secondary(b) + } diff --git a/core/src/test/scala-3/cats/derived/ReducibleTests.scala b/core/src/test/scala-3/cats/derived/ReducibleTests.scala index d327918e..78035df2 100644 --- a/core/src/test/scala-3/cats/derived/ReducibleTests.scala +++ b/core/src/test/scala-3/cats/derived/ReducibleTests.scala @@ -3,6 +3,7 @@ package cats.derived import cats.Reducible import cats.data.NonEmptyList import cats.derived.all._ +import scala.compiletime._ class ReducibleTests { From 1fc319bc10d66dea67e3dff373ae7b3ba78bd566 Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Thu, 3 Jun 2021 15:48:47 +0300 Subject: [PATCH 2/7] Finally --- core/src/main/scala-3/cats/derived/alt.scala | 31 ++++++++++++++++ .../src/main/scala-3/cats/derived/empty.scala | 17 +++------ .../main/scala-3/cats/derived/foldable.scala | 30 ++++++--------- .../main/scala-3/cats/derived/functor.scala | 13 +++---- .../main/scala-3/cats/derived/orelse.scala | 19 ---------- .../main/scala-3/cats/derived/reducible.scala | 37 ++++++++----------- .../main/scala-3/cats/derived/traverse.scala | 32 +++++++--------- .../scala-3/cats/derived/EmptyTests.scala | 2 +- .../scala-3/cats/derived/ReducibleTests.scala | 9 ++++- 9 files changed, 88 insertions(+), 102 deletions(-) create mode 100644 core/src/main/scala-3/cats/derived/alt.scala delete mode 100644 core/src/main/scala-3/cats/derived/orelse.scala diff --git a/core/src/main/scala-3/cats/derived/alt.scala b/core/src/main/scala-3/cats/derived/alt.scala new file mode 100644 index 00000000..db5f2a65 --- /dev/null +++ b/core/src/main/scala-3/cats/derived/alt.scala @@ -0,0 +1,31 @@ +package cats.derived + +import shapeless3.deriving.* +import scala.annotation.* +import scala.compiletime.* + +opaque type Alt[A, B] = A | B +object Alt extends AltInstances: + type Of0[F[_], G[_]] = [x] =>> Alt[F[x], G[x]] + type Of1[F[_[_]], G[_[_]]] = [x[_]] =>> Alt[F[x], G[x]] + type Of11[F[_[_[_]]], G[_[_[_]]]] = [x[_[_]]] =>> Alt[F[x], G[x]] + type Of2[F[_[_, _]], G[_[_, _]]] = [x[_, _]] =>> Alt[F[x], G[x]] + + def primary[A, B](a: A): Alt[A, B] = a + def secondary[A, B](b: B): Alt[A, B] = b + + extension [A, B](alt: Alt[A, B]) def unify: A | B = alt + extension [I[f[_], t] <: K0.Instances[f, t], F[_], G[x] <: F[x], T] + (inst: I[Of0[F, G], T]) @targetName("unifyK0") def unify: I[F, T] = inst + extension [I[f[_[_]], t[_]] <: K1.Instances[f, t], F[_[_]], G[x[_]] <: F[x], T[_]] + (inst: I[Of1[F, G], T]) @targetName("unifyK1") def unify: I[F, T] = inst + extension [I[f[_[_[_]]], t[_[_]]] <: K11.Instances[f, t], F[_[_[_]]], G[x[_[_]]] <: F[x], T[_[_]]] + (inst: I[Of11[F, G], T]) @targetName("unifyK11") def unify: I[F, T] = inst + extension [I[f[_[_, _]], t[_, _]] <: K2.Instances[f, t], F[_[_, _]], G[x[_, _]] <: F[x], T[_, _]] + (inst: I[Of2[F, G], T]) @targetName("unifyK2") def unify: I[F, T] = inst + +private[derived] sealed abstract class AltInstances: + inline given [A, B]: Alt[A, B] = summonFrom { + case a: A => Alt.primary(a) + case b: B => Alt.secondary(b) + } diff --git a/core/src/main/scala-3/cats/derived/empty.scala b/core/src/main/scala-3/cats/derived/empty.scala index 0260d426..7290f260 100644 --- a/core/src/main/scala-3/cats/derived/empty.scala +++ b/core/src/main/scala-3/cats/derived/empty.scala @@ -11,20 +11,13 @@ trait DerivedEmpty[A] extends Empty[A]: lazy val empty: A = emptyValue() object DerivedEmpty: - inline given [A]: DerivedEmpty[A] = summonFrom { - case given Empty[A] => delegated - case given K0.ProductInstances[DerivedEmpty, A] => product - case given K0.CoproductGeneric[A] => coproduct - } - - def delegated[A](using A: => Empty[A]): DerivedEmpty[A] = - () => A.empty + type Of[A] = Alt[Empty[A], DerivedEmpty[A]] - def product[A](using inst: K0.ProductInstances[DerivedEmpty, A]): DerivedEmpty[A] = - () => inst.construct([A] => (A: DerivedEmpty[A]) => A.empty) + given product[A](using inst: K0.ProductInstances[Of, A]): DerivedEmpty[A] = + () => inst.unify.construct([A] => (A: Empty[A]) => A.empty) - inline def coproduct[A](using gen: K0.CoproductGeneric[A]): DerivedEmpty[A] = - K0.summonFirst[DerivedEmpty, gen.MirroredElemTypes, A] + inline given coproduct[A](using gen: K0.CoproductGeneric[A]): DerivedEmpty[A] = + () => K0.summonFirst[Of, gen.MirroredElemTypes, A].unify.empty trait EmptyDerivation: extension (E: Empty.type) diff --git a/core/src/main/scala-3/cats/derived/foldable.scala b/core/src/main/scala-3/cats/derived/foldable.scala index 2f4be05f..143c4a76 100644 --- a/core/src/main/scala-3/cats/derived/foldable.scala +++ b/core/src/main/scala-3/cats/derived/foldable.scala @@ -2,27 +2,27 @@ package cats.derived import cats.{Eval, Foldable} import shapeless3.deriving.{Const, Continue, K1} -import scala.annotation.threadUnsafe object foldable extends FoldableDerivation, Instances trait DerivedFoldable[F[_]] extends Foldable[F] -object DerivedFoldable extends DerivedFoldableLowPriority: +object DerivedFoldable: + type Of[F[_]] = Alt[Foldable[F], DerivedFoldable[F]] + inline def apply[F[_]](using F: DerivedFoldable[F]): DerivedFoldable[F] = F + given const[T]: DerivedFoldable[Const[T]] with 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 delegated[F[_]](using F: => Foldable[F]): DerivedFoldable[F] = - new Delegated(F) - - given composed[F[_]: DerivedFoldable, G[_]: DerivedFoldable]: DerivedFoldable[[x] =>> F[G[x]]] = - new Delegated(Foldable[F].compose[G]) + given composed[F[_], G[_]](using F: Of[F], G: Of[G]): DerivedFoldable[[x] =>> F[G[x]]] with + private val underlying = F.unify `compose` G.unify + export underlying.* - def product[F[_]](using K1.ProductInstances[DerivedFoldable, F]): DerivedFoldable[F] = - new Product[DerivedFoldable, F] {} + given product[F[_]](using inst: K1.ProductInstances[Of, F]): DerivedFoldable[F] = + new Product(using inst.unify) {} - def coproduct[F[_]](using K1.CoproductInstances[DerivedFoldable, F]): DerivedFoldable[F] = - new Coproduct[DerivedFoldable, F] {} + given coproduct[F[_]](using inst: => K1.CoproductInstances[Of, F]): DerivedFoldable[F] = + new Coproduct(using inst.unify) {} trait Product[T[x[_]] <: Foldable[x], F[_]](using inst: K1.ProductInstances[T, F]) extends DerivedFoldable[F]: @@ -50,14 +50,6 @@ object DerivedFoldable extends DerivedFoldableLowPriority: Eval.defer(tf.foldRight(fa, lb)(f)) } - private final class Delegated[F[_]](F: => Foldable[F]) extends DerivedFoldable[F]: - @threadUnsafe private lazy val underlying = F - export underlying._ - -private[derived] sealed abstract class DerivedFoldableLowPriority: - inline given derived[F[_]](using gen: K1.Generic[F]): DerivedFoldable[F] = - gen.derive(DerivedFoldable.product, DerivedFoldable.coproduct) - trait FoldableDerivation: extension (F: Foldable.type) def derived[F[_]](using instance: DerivedFoldable[F]): Foldable[F] = instance diff --git a/core/src/main/scala-3/cats/derived/functor.scala b/core/src/main/scala-3/cats/derived/functor.scala index f6dc718d..b335bdb6 100644 --- a/core/src/main/scala-3/cats/derived/functor.scala +++ b/core/src/main/scala-3/cats/derived/functor.scala @@ -2,26 +2,23 @@ package cats.derived import cats.Functor import shapeless3.deriving.{Const, K1} -import scala.annotation.threadUnsafe object functor extends FunctorDerivation, Instances trait DerivedFunctor[F[_]] extends Functor[F] object DerivedFunctor: - type Of[F[_]] = Functor[F] OrElse DerivedFunctor[F] + type Of[F[_]] = Alt[Functor[F], DerivedFunctor[F]] + inline def apply[F[_]](using F: DerivedFunctor[F]): DerivedFunctor[F] = F given const[T]: DerivedFunctor[Const[T]] with def map[A, B](fa: T)(f: A => B): T = fa given composed[F[_], G[_]](using F: Of[F], G: Of[G]): DerivedFunctor[[x] =>> F[G[x]]] with private val underlying = F.unify `compose` G.unify - export underlying._ + export underlying.* - inline given derived[F[_]](using K1.Generic[F]): DerivedFunctor[F] = - generic - - def generic[F[_]](using inst: K1.Instances[Of, F]): DerivedFunctor[F] = - new Generic[Functor, F](using inst.unify) {} + given generic[F[_]](using inst: => K1.Instances[Of, F]): DerivedFunctor[F] = + new Generic(using inst.unify) {} trait Generic[T[x[_]] <: Functor[x], F[_]](using inst: K1.Instances[T, F]) extends DerivedFunctor[F]: diff --git a/core/src/main/scala-3/cats/derived/orelse.scala b/core/src/main/scala-3/cats/derived/orelse.scala deleted file mode 100644 index af390e72..00000000 --- a/core/src/main/scala-3/cats/derived/orelse.scala +++ /dev/null @@ -1,19 +0,0 @@ -package cats.derived - -import shapeless3.deriving.K1 -import scala.compiletime._ - -opaque type OrElse[A, B] = A | B -object OrElse extends OrElseInstances: - def primary[A, B](a: A): A OrElse B = a - def secondary[A, B](b: => B): A OrElse B = b - extension [A, B](or: A OrElse B) - def unify: A | B = or - extension [A[_[_]], B[x[_]] <: A[x], F[_]](inst: K1.Instances[[x[_]] =>> A[x] OrElse B[x], F]) - def unify: K1.Instances[A, F] = inst - -private[derived] sealed abstract class OrElseInstances: - inline given [A, B]: OrElse[A, B] = summonFrom { - case a: A => OrElse.primary(a) - case b: B => OrElse.secondary(b) - } diff --git a/core/src/main/scala-3/cats/derived/reducible.scala b/core/src/main/scala-3/cats/derived/reducible.scala index 83f47c57..31f555cd 100644 --- a/core/src/main/scala-3/cats/derived/reducible.scala +++ b/core/src/main/scala-3/cats/derived/reducible.scala @@ -2,23 +2,28 @@ package cats.derived import cats.{Eval, Foldable, Reducible} import shapeless3.deriving.{Continue, Const, K1} -import scala.annotation.threadUnsafe object reducible extends ReducibleDerivation trait DerivedReducible[F[_]] extends Reducible[F] -object DerivedReducible extends DerivedReducibleLowPriority: - given delegated[F[_]](using F: => Reducible[F]): DerivedReducible[F] = - new Delegated(F) +object DerivedReducible: + type Of[F[_]] = Alt[Reducible[F], DerivedReducible[F]] + inline def apply[F[_]](using F: DerivedReducible[F]): DerivedReducible[F] = F - given composed[F[_]: DerivedReducible, G[_]: DerivedReducible]: DerivedReducible[[x] =>> F[G[x]]] = - new Delegated(Reducible[F].compose[G]) + given composed[F[_], G[_]](using F: Of[F], G: Of[G]): DerivedReducible[[x] =>> F[G[x]]] with + private val underlying = F.unify `compose` G.unify + export underlying.* - def product[F[_]](ev: Reducible[?])(using K1.ProductInstances[DerivedFoldable, F]): DerivedReducible[F] = - new Product[DerivedFoldable, F](ev) {} + def product[F[_]](ev: Of[Const[Any]])(using inst: K1.ProductInstances[DerivedFoldable.Of, F]): DerivedReducible[F] = + given K1.ProductInstances[Foldable, F] = inst.unify + new Product[Foldable, F](ev.unify) {} - def coproduct[F[_]](using K1.CoproductInstances[DerivedReducible, F]): DerivedReducible[F] = - new Coproduct[DerivedReducible, F] {} + given coproduct[F[_]](using inst: => K1.CoproductInstances[Of, F]): DerivedReducible[F] = + given K1.CoproductInstances[Reducible, F] = inst.unify + new Coproduct[Reducible, F] {} + + inline given [F[_]](using gen: K1.ProductGeneric[F]): DerivedReducible[F] = + DerivedReducible.product(K1.summonFirst[DerivedReducible.Of, gen.MirroredElemTypes, Const[Any]]) trait Product[T[x[_]] <: Foldable[x], F[_]](ev: Reducible[?])(using inst: K1.ProductInstances[T, F]) extends DerivedFoldable.Product[T, F], DerivedReducible[F]: @@ -55,18 +60,6 @@ object DerivedReducible extends DerivedReducibleLowPriority: Eval.defer(tf.reduceRightTo(fa)(f)(g)) } - private final class Delegated[F[_]](F: => Reducible[F]) extends DerivedReducible[F]: - @threadUnsafe private lazy val underlying = F - export underlying._ - -private[derived] sealed abstract class DerivedReducibleLowPriority: - inline given derived[F[_]](using gen: K1.Generic[F]): DerivedReducible[F] = - inline gen match - case given K1.ProductGeneric[F] => - DerivedReducible.product(K1.summonFirst[DerivedReducible, gen.MirroredElemTypes, Const[Any]]) - case given K1.CoproductGeneric[F] => - DerivedReducible.coproduct - trait ReducibleDerivation: extension (F: Reducible.type) def derived[F[_]](using instance: DerivedReducible[F]): Reducible[F] = instance diff --git a/core/src/main/scala-3/cats/derived/traverse.scala b/core/src/main/scala-3/cats/derived/traverse.scala index 866666ba..0ef1197f 100644 --- a/core/src/main/scala-3/cats/derived/traverse.scala +++ b/core/src/main/scala-3/cats/derived/traverse.scala @@ -2,29 +2,31 @@ package cats.derived import cats.{Applicative, Eval, Traverse} import shapeless3.deriving.{Const, Continue, K1} -import scala.annotation.threadUnsafe object traverse extends TraverseDerivation, Instances trait DerivedTraverse[F[_]] extends Traverse[F] -object DerivedTraverse extends DerivedTraverseLowPriority: +object DerivedTraverse: + type Of[F[_]] = Alt[Traverse[F], DerivedTraverse[F]] + inline def apply[F[_]](using F: DerivedTraverse[F]): DerivedTraverse[F] = F + given const[T]: DerivedTraverse[Const[T]] with override def map[A, B](fa: T)(f: A => B): T = fa 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 def traverse[G[_], A, B](fa: T)(f: A => G[B])(using G: Applicative[G]): G[T] = G.pure(fa) - given delegated[F[_]](using F: => Traverse[F]): DerivedTraverse[F] = - new Delegated(F) - - given composed[F[_]: DerivedTraverse, G[_]: DerivedTraverse]: DerivedTraverse[[x] =>> F[G[x]]] = - new Delegated(Traverse[F].compose[G]) + given composed[F[_], G[_]](using F: Of[F], G: Of[G]): DerivedTraverse[[x] =>> F[G[x]]] with + private val underlying = F.unify `compose` G.unify + export underlying.* - def product[F[_]](using K1.ProductInstances[DerivedTraverse, F]): DerivedTraverse[F] = - new Product[DerivedTraverse, F] {} + given product[F[_]](using inst: K1.ProductInstances[Of, F]): DerivedTraverse[F] = + given K1.ProductInstances[Traverse, F] = inst.unify + new Product[Traverse, F] {} - def coproduct[F[_]](using K1.CoproductInstances[DerivedTraverse, F]): DerivedTraverse[F] = - new Coproduct[DerivedTraverse, F] {} + given coproduct[F[_]](using inst: => K1.CoproductInstances[Of, F]): DerivedTraverse[F] = + given K1.CoproductInstances[Traverse, F] = inst.unify + new Coproduct[Traverse, F] {} trait Product[T[x[_]] <: Traverse[x], F[_]](using inst: K1.ProductInstances[T, F]) extends DerivedFunctor.Generic[T, F], DerivedFoldable.Product[T, F], DerivedTraverse[F]: @@ -54,14 +56,6 @@ object DerivedTraverse extends DerivedTraverseLowPriority: tf.traverse(fa)(f) } - private final class Delegated[F[_]](F: => Traverse[F]) extends DerivedTraverse[F]: - @threadUnsafe private lazy val underlying = F - export underlying._ - -private[derived] sealed abstract class DerivedTraverseLowPriority: - inline given derived[F[_]](using gen: K1.Generic[F]): DerivedTraverse[F] = - gen.derive(DerivedTraverse.product, DerivedTraverse.coproduct) - trait TraverseDerivation: extension (F: Traverse.type) def derived[F[_]](using instance: DerivedTraverse[F]): Traverse[F] = instance diff --git a/core/src/test/scala-3/cats/derived/EmptyTests.scala b/core/src/test/scala-3/cats/derived/EmptyTests.scala index 3390e681..b6823d25 100644 --- a/core/src/test/scala-3/cats/derived/EmptyTests.scala +++ b/core/src/test/scala-3/cats/derived/EmptyTests.scala @@ -4,7 +4,7 @@ import alleycats._ import cats._ import cats.derived.all._ -class EmptyTests: +object EmptyTests: case class Foo(i: Int, b: IntTree) derives Empty enum IntTree: case Leaf diff --git a/core/src/test/scala-3/cats/derived/ReducibleTests.scala b/core/src/test/scala-3/cats/derived/ReducibleTests.scala index 78035df2..14f31b3f 100644 --- a/core/src/test/scala-3/cats/derived/ReducibleTests.scala +++ b/core/src/test/scala-3/cats/derived/ReducibleTests.scala @@ -5,7 +5,7 @@ import cats.data.NonEmptyList import cats.derived.all._ import scala.compiletime._ -class ReducibleTests { +object ReducibleTests { case class Box[A](value: A) derives Reducible @@ -27,6 +27,11 @@ class ReducibleTests { case Non case Con(v: A, r: MyList[A]) - summon[DerivedFunctor[MyList]] + import cats._ + + DerivedFunctor[MyList] summon[DerivedReducible[NonEmptyTree]] } + +@main def run() = + println(DerivedFunctor[ReducibleTests.MyList].map(ReducibleTests.MyList.Con(42, ReducibleTests.MyList.Non))(_.toString)) From 110ac852b09721109e745e9b890a8101894f1ca9 Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Thu, 3 Jun 2021 15:51:01 +0300 Subject: [PATCH 3/7] Transparent inline for Alt --- core/src/main/scala-3/cats/derived/alt.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala-3/cats/derived/alt.scala b/core/src/main/scala-3/cats/derived/alt.scala index db5f2a65..005fb8eb 100644 --- a/core/src/main/scala-3/cats/derived/alt.scala +++ b/core/src/main/scala-3/cats/derived/alt.scala @@ -25,7 +25,7 @@ object Alt extends AltInstances: (inst: I[Of2[F, G], T]) @targetName("unifyK2") def unify: I[F, T] = inst private[derived] sealed abstract class AltInstances: - inline given [A, B]: Alt[A, B] = summonFrom { + transparent inline given [A, B]: Alt[A, B] = summonFrom { case a: A => Alt.primary(a) case b: B => Alt.secondary(b) } From 4c0a67ba258a2ea6dbf426521b50ce2c889a5116 Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Thu, 3 Jun 2021 15:54:46 +0300 Subject: [PATCH 4/7] Simpler --- core/src/main/scala-3/cats/derived/reducible.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala-3/cats/derived/reducible.scala b/core/src/main/scala-3/cats/derived/reducible.scala index 31f555cd..e2373190 100644 --- a/core/src/main/scala-3/cats/derived/reducible.scala +++ b/core/src/main/scala-3/cats/derived/reducible.scala @@ -14,16 +14,16 @@ object DerivedReducible: private val underlying = F.unify `compose` G.unify export underlying.* - def product[F[_]](ev: Of[Const[Any]])(using inst: K1.ProductInstances[DerivedFoldable.Of, F]): DerivedReducible[F] = + def product[F[_]](ev: Reducible[?])(using inst: K1.ProductInstances[DerivedFoldable.Of, F]): DerivedReducible[F] = given K1.ProductInstances[Foldable, F] = inst.unify - new Product[Foldable, F](ev.unify) {} + new Product[Foldable, F](ev) {} given coproduct[F[_]](using inst: => K1.CoproductInstances[Of, F]): DerivedReducible[F] = given K1.CoproductInstances[Reducible, F] = inst.unify new Coproduct[Reducible, F] {} inline given [F[_]](using gen: K1.ProductGeneric[F]): DerivedReducible[F] = - DerivedReducible.product(K1.summonFirst[DerivedReducible.Of, gen.MirroredElemTypes, Const[Any]]) + product(K1.summonFirst[Of, gen.MirroredElemTypes, Const[Any]].unify) trait Product[T[x[_]] <: Foldable[x], F[_]](ev: Reducible[?])(using inst: K1.ProductInstances[T, F]) extends DerivedFoldable.Product[T, F], DerivedReducible[F]: From 2cd9bbafc3d6f17fb83671a3c319a1ac5d0450e5 Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Thu, 3 Jun 2021 16:11:40 +0300 Subject: [PATCH 5/7] threadUnsafe Empty --- core/src/main/scala-3/cats/derived/empty.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala-3/cats/derived/empty.scala b/core/src/main/scala-3/cats/derived/empty.scala index 7290f260..879ad581 100644 --- a/core/src/main/scala-3/cats/derived/empty.scala +++ b/core/src/main/scala-3/cats/derived/empty.scala @@ -2,13 +2,13 @@ package cats.derived import alleycats.Empty import shapeless3.deriving.K0 -import scala.compiletime.summonFrom +import scala.annotation.* object empty extends EmptyDerivation trait DerivedEmpty[A] extends Empty[A]: protected def emptyValue(): A - lazy val empty: A = emptyValue() + @threadUnsafe lazy val empty: A = emptyValue() object DerivedEmpty: type Of[A] = Alt[Empty[A], DerivedEmpty[A]] From 10e6d02e8e8609c1f2c843503a61d87be1b785d6 Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Thu, 3 Jun 2021 19:36:57 +0300 Subject: [PATCH 6/7] Generic Derived and opaque types --- core/src/main/scala-3/cats/derived/alt.scala | 48 ++++++++++--------- .../src/main/scala-3/cats/derived/empty.scala | 19 ++++---- .../main/scala-3/cats/derived/foldable.scala | 26 +++++----- .../main/scala-3/cats/derived/functor.scala | 22 +++++---- .../main/scala-3/cats/derived/reducible.scala | 31 ++++++------ .../main/scala-3/cats/derived/traverse.scala | 26 +++++----- .../scala-3/cats/derived/ReducibleTests.scala | 3 ++ 7 files changed, 95 insertions(+), 80 deletions(-) diff --git a/core/src/main/scala-3/cats/derived/alt.scala b/core/src/main/scala-3/cats/derived/alt.scala index 005fb8eb..6c6c0ddc 100644 --- a/core/src/main/scala-3/cats/derived/alt.scala +++ b/core/src/main/scala-3/cats/derived/alt.scala @@ -4,28 +4,32 @@ import shapeless3.deriving.* import scala.annotation.* import scala.compiletime.* -opaque type Alt[A, B] = A | B -object Alt extends AltInstances: - type Of0[F[_], G[_]] = [x] =>> Alt[F[x], G[x]] - type Of1[F[_[_]], G[_[_]]] = [x[_]] =>> Alt[F[x], G[x]] - type Of11[F[_[_[_]]], G[_[_[_]]]] = [x[_[_]]] =>> Alt[F[x], G[x]] - type Of2[F[_[_, _]], G[_[_, _]]] = [x[_, _]] =>> Alt[F[x], G[x]] +opaque type Derived[A] = A +object Derived: + def apply[A](instance: A): Derived[A] = instance + extension [A](derived: Derived[A]) def instance: A = derived + given [A]: Conversion[A, Derived[A]] = apply - def primary[A, B](a: A): Alt[A, B] = a - def secondary[A, B](b: B): Alt[A, B] = b + type Or0[F[_]] = [x] =>> Or[F[x]] + type Or1[F[_[_]]] = [x[_]] =>> Or[F[x]] + type Or11[F[_[_[_]]]] = [x[_[_]]] =>> Or[F[x]] + type Or2[F[_[_, _]]] = [x[_, _]] =>> Or[F[x]] - extension [A, B](alt: Alt[A, B]) def unify: A | B = alt - extension [I[f[_], t] <: K0.Instances[f, t], F[_], G[x] <: F[x], T] - (inst: I[Of0[F, G], T]) @targetName("unifyK0") def unify: I[F, T] = inst - extension [I[f[_[_]], t[_]] <: K1.Instances[f, t], F[_[_]], G[x[_]] <: F[x], T[_]] - (inst: I[Of1[F, G], T]) @targetName("unifyK1") def unify: I[F, T] = inst - extension [I[f[_[_[_]]], t[_[_]]] <: K11.Instances[f, t], F[_[_[_]]], G[x[_[_]]] <: F[x], T[_[_]]] - (inst: I[Of11[F, G], T]) @targetName("unifyK11") def unify: I[F, T] = inst - extension [I[f[_[_, _]], t[_, _]] <: K2.Instances[f, t], F[_[_, _]], G[x[_, _]] <: F[x], T[_, _]] - (inst: I[Of2[F, G], T]) @targetName("unifyK2") def unify: I[F, T] = inst - -private[derived] sealed abstract class AltInstances: - transparent inline given [A, B]: Alt[A, B] = summonFrom { - case a: A => Alt.primary(a) - case b: B => Alt.secondary(b) + opaque type Or[A] = A + object Or extends OrInstances: + def apply[A](instance: A): Or[A] = instance + extension [A](or: Or[A]) def unify: A = or + extension [I[f[_], t] <: K0.Instances[f, t], F[_], T] + (inst: I[Or0[F], T]) @targetName("unifyK0") def unify: I[F, T] = inst + extension [I[f[_[_]], t[_]] <: K1.Instances[f, t], F[_[_]], T[_]] + (inst: I[Or1[F], T]) @targetName("unifyK1") def unify: I[F, T] = inst + extension [I[f[_[_[_]]], t[_[_]]] <: K11.Instances[f, t], F[_[_[_]]], T[_[_]]] + (inst: I[Or11[F], T]) @targetName("unifyK11") def unify: I[F, T] = inst + extension [I[f[_[_, _]], t[_, _]] <: K2.Instances[f, t], F[_[_, _]], T[_, _]] + (inst: I[Or2[F], T]) @targetName("unifyK2") def unify: I[F, T] = inst + +sealed abstract class OrInstances: + inline given [A]: Derived.Or[A] = summonFrom { + case instance: A => Derived.Or(instance) + case derived: Derived[A] => Derived.Or(derived.instance) } diff --git a/core/src/main/scala-3/cats/derived/empty.scala b/core/src/main/scala-3/cats/derived/empty.scala index 879ad581..62d71e61 100644 --- a/core/src/main/scala-3/cats/derived/empty.scala +++ b/core/src/main/scala-3/cats/derived/empty.scala @@ -2,23 +2,22 @@ package cats.derived import alleycats.Empty import shapeless3.deriving.K0 -import scala.annotation.* +import scala.compiletime.* object empty extends EmptyDerivation -trait DerivedEmpty[A] extends Empty[A]: - protected def emptyValue(): A - @threadUnsafe lazy val empty: A = emptyValue() - +type DerivedEmpty[A] = Derived[Empty[A]] object DerivedEmpty: - type Of[A] = Alt[Empty[A], DerivedEmpty[A]] + type Or[A] = Derived.Or[Empty[A]] - given product[A](using inst: K0.ProductInstances[Of, A]): DerivedEmpty[A] = - () => inst.unify.construct([A] => (A: Empty[A]) => A.empty) + given product[A](using inst: K0.ProductInstances[Or, A]): DerivedEmpty[A] = + Empty(inst.unify.construct([A] => (A: Empty[A]) => A.empty)) inline given coproduct[A](using gen: K0.CoproductGeneric[A]): DerivedEmpty[A] = - () => K0.summonFirst[Of, gen.MirroredElemTypes, A].unify.empty + K0.summonFirst[Or, gen.MirroredElemTypes, A].unify trait EmptyDerivation: extension (E: Empty.type) - def derived[A](using instance: DerivedEmpty[A]): Empty[A] = instance + inline def derived[A]: Empty[A] = + import DerivedEmpty.given + summonInline[DerivedEmpty[A]].instance diff --git a/core/src/main/scala-3/cats/derived/foldable.scala b/core/src/main/scala-3/cats/derived/foldable.scala index 143c4a76..63d18296 100644 --- a/core/src/main/scala-3/cats/derived/foldable.scala +++ b/core/src/main/scala-3/cats/derived/foldable.scala @@ -2,30 +2,30 @@ package cats.derived import cats.{Eval, Foldable} import shapeless3.deriving.{Const, Continue, K1} +import scala.compiletime.* object foldable extends FoldableDerivation, Instances -trait DerivedFoldable[F[_]] extends Foldable[F] +type DerivedFoldable[F[_]] = Derived[Foldable[F]] object DerivedFoldable: - type Of[F[_]] = Alt[Foldable[F], DerivedFoldable[F]] - inline def apply[F[_]](using F: DerivedFoldable[F]): DerivedFoldable[F] = F + type Or[F[_]] = Derived.Or[Foldable[F]] + inline def apply[F[_]](using F: DerivedFoldable[F]): Foldable[F] = F.instance - given const[T]: DerivedFoldable[Const[T]] with + given [T]: DerivedFoldable[Const[T]] = new Foldable[Const[T]]: 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 composed[F[_], G[_]](using F: Of[F], G: Of[G]): DerivedFoldable[[x] =>> F[G[x]]] with - private val underlying = F.unify `compose` G.unify - export underlying.* + given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedFoldable[[x] =>> F[G[x]]] = + F.unify `compose` G.unify - given product[F[_]](using inst: K1.ProductInstances[Of, F]): DerivedFoldable[F] = + given [F[_]](using inst: K1.ProductInstances[Or, F]): DerivedFoldable[F] = new Product(using inst.unify) {} - given coproduct[F[_]](using inst: => K1.CoproductInstances[Of, F]): DerivedFoldable[F] = + given [F[_]](using inst: => K1.CoproductInstances[Or, F]): DerivedFoldable[F] = new Coproduct(using inst.unify) {} trait Product[T[x[_]] <: Foldable[x], F[_]](using inst: K1.ProductInstances[T, F]) - extends DerivedFoldable[F]: + extends Foldable[F]: 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]) => @@ -38,7 +38,7 @@ object DerivedFoldable: } trait Coproduct[T[x[_]] <: Foldable[x], F[_]](using inst: K1.CoproductInstances[T, F]) - extends DerivedFoldable[F]: + extends Foldable[F]: 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]) => @@ -52,4 +52,6 @@ object DerivedFoldable: trait FoldableDerivation: extension (F: Foldable.type) - def derived[F[_]](using instance: DerivedFoldable[F]): Foldable[F] = instance + inline def derived[F[_]]: Foldable[F] = + import DerivedFoldable.given + summonInline[DerivedFoldable[F]].instance diff --git a/core/src/main/scala-3/cats/derived/functor.scala b/core/src/main/scala-3/cats/derived/functor.scala index b335bdb6..35c624c3 100644 --- a/core/src/main/scala-3/cats/derived/functor.scala +++ b/core/src/main/scala-3/cats/derived/functor.scala @@ -2,26 +2,26 @@ package cats.derived import cats.Functor import shapeless3.deriving.{Const, K1} +import scala.compiletime.* object functor extends FunctorDerivation, Instances -trait DerivedFunctor[F[_]] extends Functor[F] +type DerivedFunctor[F[_]] = Derived[Functor[F]] object DerivedFunctor: - type Of[F[_]] = Alt[Functor[F], DerivedFunctor[F]] - inline def apply[F[_]](using F: DerivedFunctor[F]): DerivedFunctor[F] = F + type Or[F[_]] = Derived.Or[Functor[F]] + inline def apply[F[_]](using F: DerivedFunctor[F]): Functor[F] = F.instance - given const[T]: DerivedFunctor[Const[T]] with + given [T]: DerivedFunctor[Const[T]] = new Functor[Const[T]]: def map[A, B](fa: T)(f: A => B): T = fa - given composed[F[_], G[_]](using F: Of[F], G: Of[G]): DerivedFunctor[[x] =>> F[G[x]]] with - private val underlying = F.unify `compose` G.unify - export underlying.* + given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedFunctor[[x] =>> F[G[x]]] = + F.unify `compose` G.unify - given generic[F[_]](using inst: => K1.Instances[Of, F]): DerivedFunctor[F] = + given [F[_]](using inst: => K1.Instances[Or, F]): DerivedFunctor[F] = new Generic(using inst.unify) {} trait Generic[T[x[_]] <: Functor[x], F[_]](using inst: K1.Instances[T, F]) - extends DerivedFunctor[F]: + extends Functor[F]: def map[A, B](fa: F[A])(f: A => B): F[B] = inst.map(fa: F[A]) { [f[_]] => (tf: T[f], fa: f[A]) => @@ -30,4 +30,6 @@ object DerivedFunctor: trait FunctorDerivation: extension (F: Functor.type) - def derived[F[_]](using instance: DerivedFunctor[F]): Functor[F] = instance + inline def derived[F[_]]: Functor[F] = + import DerivedFunctor.given + summonInline[DerivedFunctor[F]].instance diff --git a/core/src/main/scala-3/cats/derived/reducible.scala b/core/src/main/scala-3/cats/derived/reducible.scala index e2373190..f8de93f6 100644 --- a/core/src/main/scala-3/cats/derived/reducible.scala +++ b/core/src/main/scala-3/cats/derived/reducible.scala @@ -2,31 +2,31 @@ package cats.derived import cats.{Eval, Foldable, Reducible} import shapeless3.deriving.{Continue, Const, K1} +import scala.compiletime.* object reducible extends ReducibleDerivation -trait DerivedReducible[F[_]] extends Reducible[F] +type DerivedReducible[F[_]] = Derived[Reducible[F]] object DerivedReducible: - type Of[F[_]] = Alt[Reducible[F], DerivedReducible[F]] - inline def apply[F[_]](using F: DerivedReducible[F]): DerivedReducible[F] = F + type Or[F[_]] = Derived.Or[Reducible[F]] + inline def apply[F[_]](using F: DerivedReducible[F]): Reducible[F] = F.instance - given composed[F[_], G[_]](using F: Of[F], G: Of[G]): DerivedReducible[[x] =>> F[G[x]]] with - private val underlying = F.unify `compose` G.unify - export underlying.* + given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedReducible[[x] =>> F[G[x]]] = + F.unify `compose` G.unify - def product[F[_]](ev: Reducible[?])(using inst: K1.ProductInstances[DerivedFoldable.Of, F]): DerivedReducible[F] = + def product[F[_]](ev: Reducible[?])(using inst: K1.ProductInstances[DerivedFoldable.Or, F]): DerivedReducible[F] = given K1.ProductInstances[Foldable, F] = inst.unify new Product[Foldable, F](ev) {} - given coproduct[F[_]](using inst: => K1.CoproductInstances[Of, F]): DerivedReducible[F] = + inline given [F[_]](using gen: K1.ProductGeneric[F]): DerivedReducible[F] = + product(K1.summonFirst[Or, gen.MirroredElemTypes, Const[Any]].unify) + + given [F[_]](using inst: => K1.CoproductInstances[Or, F]): DerivedReducible[F] = given K1.CoproductInstances[Reducible, F] = inst.unify new Coproduct[Reducible, F] {} - inline given [F[_]](using gen: K1.ProductGeneric[F]): DerivedReducible[F] = - product(K1.summonFirst[Of, gen.MirroredElemTypes, Const[Any]].unify) - trait Product[T[x[_]] <: Foldable[x], F[_]](ev: Reducible[?])(using inst: K1.ProductInstances[T, F]) - extends DerivedFoldable.Product[T, F], DerivedReducible[F]: + extends DerivedFoldable.Product[T, F], Reducible[F]: private val evalNone = Eval.now(None) @@ -48,7 +48,7 @@ object DerivedReducible: ).map(_.get) trait Coproduct[T[x[_]] <: Reducible[x], F[_]](using inst: K1.CoproductInstances[T, F]) - extends DerivedFoldable.Coproduct[T, F], DerivedReducible[F]: + extends DerivedFoldable.Coproduct[T, F], Reducible[F]: 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]) => @@ -62,4 +62,7 @@ object DerivedReducible: trait ReducibleDerivation: extension (F: Reducible.type) - def derived[F[_]](using instance: DerivedReducible[F]): Reducible[F] = instance + inline def derived[F[_]]: Reducible[F] = + import DerivedFoldable.given + import DerivedReducible.given + summonInline[DerivedReducible[F]].instance diff --git a/core/src/main/scala-3/cats/derived/traverse.scala b/core/src/main/scala-3/cats/derived/traverse.scala index 0ef1197f..fef20560 100644 --- a/core/src/main/scala-3/cats/derived/traverse.scala +++ b/core/src/main/scala-3/cats/derived/traverse.scala @@ -2,34 +2,34 @@ package cats.derived import cats.{Applicative, Eval, Traverse} import shapeless3.deriving.{Const, Continue, K1} +import scala.compiletime.* object traverse extends TraverseDerivation, Instances -trait DerivedTraverse[F[_]] extends Traverse[F] +type DerivedTraverse[F[_]] = Derived[Traverse[F]] object DerivedTraverse: - type Of[F[_]] = Alt[Traverse[F], DerivedTraverse[F]] - inline def apply[F[_]](using F: DerivedTraverse[F]): DerivedTraverse[F] = F + type Or[F[_]] = Derived.Or[Traverse[F]] + inline def apply[F[_]](using F: DerivedTraverse[F]): Traverse[F] = F.instance - given const[T]: DerivedTraverse[Const[T]] with + given [T]: DerivedTraverse[Const[T]] = new Traverse[Const[T]]: override def map[A, B](fa: T)(f: A => B): T = fa 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 def traverse[G[_], A, B](fa: T)(f: A => G[B])(using G: Applicative[G]): G[T] = G.pure(fa) - given composed[F[_], G[_]](using F: Of[F], G: Of[G]): DerivedTraverse[[x] =>> F[G[x]]] with - private val underlying = F.unify `compose` G.unify - export underlying.* + given [F[_], G[_]](using F: Or[F], G: Or[G]): DerivedTraverse[[x] =>> F[G[x]]] = + F.unify `compose` G.unify - given product[F[_]](using inst: K1.ProductInstances[Of, F]): DerivedTraverse[F] = + given [F[_]](using inst: K1.ProductInstances[Or, F]): DerivedTraverse[F] = given K1.ProductInstances[Traverse, F] = inst.unify new Product[Traverse, F] {} - given coproduct[F[_]](using inst: => K1.CoproductInstances[Of, F]): DerivedTraverse[F] = + given [F[_]](using inst: => K1.CoproductInstances[Or, F]): DerivedTraverse[F] = given K1.CoproductInstances[Traverse, F] = inst.unify new Coproduct[Traverse, F] {} trait Product[T[x[_]] <: Traverse[x], F[_]](using inst: K1.ProductInstances[T, F]) - extends DerivedFunctor.Generic[T, F], DerivedFoldable.Product[T, F], DerivedTraverse[F]: + extends DerivedFunctor.Generic[T, F], DerivedFoldable.Product[T, F], Traverse[F]: def traverse[G[_], A, B](fa: F[A])(f: A => G[B])(using G: Applicative[G]): G[F[B]] = inst.traverse[A, G, B](fa) { [a, b] => (ga: G[a], f: a => b) => @@ -43,7 +43,7 @@ object DerivedTraverse: } trait Coproduct[T[x[_]] <: Traverse[x], F[_]](using inst: K1.CoproductInstances[T, F]) - extends DerivedFunctor.Generic[T, F], DerivedFoldable.Coproduct[T, F], DerivedTraverse[F]: + extends DerivedFunctor.Generic[T, F], DerivedFoldable.Coproduct[T, F], Traverse[F]: def traverse[G[_], A, B](fa: F[A])(f: A => G[B])(using G: Applicative[G]): G[F[B]] = inst.traverse[A, G, B](fa) { [a, b] => (ga: G[a], f: a => b) => @@ -58,4 +58,6 @@ object DerivedTraverse: trait TraverseDerivation: extension (F: Traverse.type) - def derived[F[_]](using instance: DerivedTraverse[F]): Traverse[F] = instance + inline def derived[F[_]]: Traverse[F] = + import DerivedTraverse.given + summonInline[DerivedTraverse[F]].instance diff --git a/core/src/test/scala-3/cats/derived/ReducibleTests.scala b/core/src/test/scala-3/cats/derived/ReducibleTests.scala index 14f31b3f..2bd8b2fb 100644 --- a/core/src/test/scala-3/cats/derived/ReducibleTests.scala +++ b/core/src/test/scala-3/cats/derived/ReducibleTests.scala @@ -4,6 +4,9 @@ import cats.Reducible import cats.data.NonEmptyList import cats.derived.all._ import scala.compiletime._ +import DerivedFunctor.given +import DerivedFoldable.given +import DerivedReducible.given object ReducibleTests { From 81785df5d348b8e66b744d3fd5f80b345632bc66 Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Thu, 3 Jun 2021 19:48:06 +0300 Subject: [PATCH 7/7] Some tweaks --- .../cats/derived/{alt.scala => derived.scala} | 0 core/src/main/scala-3/cats/derived/empty.scala | 7 ++++--- core/src/main/scala-3/cats/derived/foldable.scala | 8 ++++---- core/src/main/scala-3/cats/derived/functor.scala | 8 ++++---- core/src/main/scala-3/cats/derived/reducible.scala | 10 +++++----- core/src/main/scala-3/cats/derived/traverse.scala | 8 ++++---- .../test/scala-3/cats/derived/ReducibleTests.scala | 12 +++--------- 7 files changed, 24 insertions(+), 29 deletions(-) rename core/src/main/scala-3/cats/derived/{alt.scala => derived.scala} (100%) diff --git a/core/src/main/scala-3/cats/derived/alt.scala b/core/src/main/scala-3/cats/derived/derived.scala similarity index 100% rename from core/src/main/scala-3/cats/derived/alt.scala rename to core/src/main/scala-3/cats/derived/derived.scala diff --git a/core/src/main/scala-3/cats/derived/empty.scala b/core/src/main/scala-3/cats/derived/empty.scala index 62d71e61..1b650c58 100644 --- a/core/src/main/scala-3/cats/derived/empty.scala +++ b/core/src/main/scala-3/cats/derived/empty.scala @@ -9,6 +9,9 @@ object empty extends EmptyDerivation type DerivedEmpty[A] = Derived[Empty[A]] object DerivedEmpty: type Or[A] = Derived.Or[Empty[A]] + inline def apply[A]: Empty[A] = + import DerivedEmpty.given + summonInline[DerivedEmpty[A]].instance given product[A](using inst: K0.ProductInstances[Or, A]): DerivedEmpty[A] = Empty(inst.unify.construct([A] => (A: Empty[A]) => A.empty)) @@ -18,6 +21,4 @@ object DerivedEmpty: trait EmptyDerivation: extension (E: Empty.type) - inline def derived[A]: Empty[A] = - import DerivedEmpty.given - summonInline[DerivedEmpty[A]].instance + inline def derived[A]: Empty[A] = DerivedEmpty[A] diff --git a/core/src/main/scala-3/cats/derived/foldable.scala b/core/src/main/scala-3/cats/derived/foldable.scala index 63d18296..f5121bf1 100644 --- a/core/src/main/scala-3/cats/derived/foldable.scala +++ b/core/src/main/scala-3/cats/derived/foldable.scala @@ -9,7 +9,9 @@ object foldable extends FoldableDerivation, Instances type DerivedFoldable[F[_]] = Derived[Foldable[F]] object DerivedFoldable: type Or[F[_]] = Derived.Or[Foldable[F]] - inline def apply[F[_]](using F: DerivedFoldable[F]): Foldable[F] = F.instance + inline def apply[F[_]]: Foldable[F] = + import DerivedFoldable.given + summonInline[DerivedFoldable[F]].instance given [T]: DerivedFoldable[Const[T]] = new Foldable[Const[T]]: def foldLeft[A, B](fa: T, b: B)(f: (B, A) => B): B = b @@ -52,6 +54,4 @@ object DerivedFoldable: trait FoldableDerivation: extension (F: Foldable.type) - inline def derived[F[_]]: Foldable[F] = - import DerivedFoldable.given - summonInline[DerivedFoldable[F]].instance + inline def derived[F[_]]: Foldable[F] = DerivedFoldable[F] diff --git a/core/src/main/scala-3/cats/derived/functor.scala b/core/src/main/scala-3/cats/derived/functor.scala index 35c624c3..aa9256c1 100644 --- a/core/src/main/scala-3/cats/derived/functor.scala +++ b/core/src/main/scala-3/cats/derived/functor.scala @@ -9,7 +9,9 @@ object functor extends FunctorDerivation, Instances type DerivedFunctor[F[_]] = Derived[Functor[F]] object DerivedFunctor: type Or[F[_]] = Derived.Or[Functor[F]] - inline def apply[F[_]](using F: DerivedFunctor[F]): Functor[F] = F.instance + inline def apply[F[_]]: Functor[F] = + import DerivedFunctor.given + summonInline[DerivedFunctor[F]].instance given [T]: DerivedFunctor[Const[T]] = new Functor[Const[T]]: def map[A, B](fa: T)(f: A => B): T = fa @@ -30,6 +32,4 @@ object DerivedFunctor: trait FunctorDerivation: extension (F: Functor.type) - inline def derived[F[_]]: Functor[F] = - import DerivedFunctor.given - summonInline[DerivedFunctor[F]].instance + inline def derived[F[_]]: Functor[F] = DerivedFunctor[F] diff --git a/core/src/main/scala-3/cats/derived/reducible.scala b/core/src/main/scala-3/cats/derived/reducible.scala index f8de93f6..36541219 100644 --- a/core/src/main/scala-3/cats/derived/reducible.scala +++ b/core/src/main/scala-3/cats/derived/reducible.scala @@ -9,7 +9,10 @@ object reducible extends ReducibleDerivation type DerivedReducible[F[_]] = Derived[Reducible[F]] object DerivedReducible: type Or[F[_]] = Derived.Or[Reducible[F]] - inline def apply[F[_]](using F: DerivedReducible[F]): Reducible[F] = F.instance + inline def apply[F[_]]: Reducible[F] = + import DerivedFoldable.given + 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 @@ -62,7 +65,4 @@ object DerivedReducible: trait ReducibleDerivation: extension (F: Reducible.type) - inline def derived[F[_]]: Reducible[F] = - import DerivedFoldable.given - import DerivedReducible.given - summonInline[DerivedReducible[F]].instance + inline def derived[F[_]]: Reducible[F] = DerivedReducible[F] diff --git a/core/src/main/scala-3/cats/derived/traverse.scala b/core/src/main/scala-3/cats/derived/traverse.scala index fef20560..f6e0c066 100644 --- a/core/src/main/scala-3/cats/derived/traverse.scala +++ b/core/src/main/scala-3/cats/derived/traverse.scala @@ -9,7 +9,9 @@ object traverse extends TraverseDerivation, Instances type DerivedTraverse[F[_]] = Derived[Traverse[F]] object DerivedTraverse: type Or[F[_]] = Derived.Or[Traverse[F]] - inline def apply[F[_]](using F: DerivedTraverse[F]): Traverse[F] = F.instance + inline def apply[F[_]]: Traverse[F] = + import DerivedTraverse.given + summonInline[DerivedTraverse[F]].instance given [T]: DerivedTraverse[Const[T]] = new Traverse[Const[T]]: override def map[A, B](fa: T)(f: A => B): T = fa @@ -58,6 +60,4 @@ object DerivedTraverse: trait TraverseDerivation: extension (F: Traverse.type) - inline def derived[F[_]]: Traverse[F] = - import DerivedTraverse.given - summonInline[DerivedTraverse[F]].instance + inline def derived[F[_]]: Traverse[F] = DerivedTraverse[F] diff --git a/core/src/test/scala-3/cats/derived/ReducibleTests.scala b/core/src/test/scala-3/cats/derived/ReducibleTests.scala index 2bd8b2fb..6eb26f80 100644 --- a/core/src/test/scala-3/cats/derived/ReducibleTests.scala +++ b/core/src/test/scala-3/cats/derived/ReducibleTests.scala @@ -2,14 +2,9 @@ package cats.derived import cats.Reducible import cats.data.NonEmptyList -import cats.derived.all._ -import scala.compiletime._ -import DerivedFunctor.given -import DerivedFoldable.given -import DerivedReducible.given - -object ReducibleTests { +import cats.derived.all.* +object ReducibleTests: case class Box[A](value: A) derives Reducible sealed trait OneOrMany[+A] derives Reducible @@ -33,8 +28,7 @@ object ReducibleTests { import cats._ DerivedFunctor[MyList] - summon[DerivedReducible[NonEmptyTree]] -} + DerivedReducible[NonEmptyTree] @main def run() = println(DerivedFunctor[ReducibleTests.MyList].map(ReducibleTests.MyList.Con(42, ReducibleTests.MyList.Non))(_.toString))