diff --git a/build.sbt b/build.sbt index 149f175..b3863f9 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,5 @@ +import com.typesafe.tools.mima.core.{DirectMissingMethodProblem, ProblemFilters} + val scala3Version = "3.3.3" ThisBuild / organization := "org.typelevel" @@ -63,6 +65,15 @@ lazy val deriving = crossProject(JSPlatform, JVMPlatform, NativePlatform) .jsEnablePlugins(ScalaJSJUnitPlugin) .nativeEnablePlugins(ScalaNativeJUnitPlugin) .settings(libraryDependencies += "org.typelevel" %%% "cats-core" % "2.10.0" % "test") + .settings( + mimaBinaryIssueFilters ++= Seq( + // Those are objects: + ProblemFilters.exclude[DirectMissingMethodProblem]("shapeless3.deriving.K0."), + ProblemFilters.exclude[DirectMissingMethodProblem]("shapeless3.deriving.K1."), + ProblemFilters.exclude[DirectMissingMethodProblem]("shapeless3.deriving.K11."), + ProblemFilters.exclude[DirectMissingMethodProblem]("shapeless3.deriving.K2.") + ) + ) lazy val derivingJVM = deriving.jvm lazy val derivingJS = deriving.js diff --git a/modules/deriving/src/main/scala/shapeless3/deriving/internals/kinds.scala b/modules/deriving/src/main/scala/shapeless3/deriving/internals/kinds.scala index 0e2b8a0..9fbf071 100644 --- a/modules/deriving/src/main/scala/shapeless3/deriving/internals/kinds.scala +++ b/modules/deriving/src/main/scala/shapeless3/deriving/internals/kinds.scala @@ -4,6 +4,14 @@ import scala.compiletime.* import scala.util.NotGiven object Kinds: + /** Like [[Tuple.Head]] but without a bounds restriction. */ + type Head[T] = T match + case h *: _ => h + + /** Like [[Tuple.Tail]] but without a bounds restriction. */ + type Tail[T] <: Tuple = T match + case _ *: t => t + transparent inline def summonFirst[T]: Any = inline erasedValue[T] match case _: (a *: b) => diff --git a/modules/deriving/src/main/scala/shapeless3/deriving/kinds.scala b/modules/deriving/src/main/scala/shapeless3/deriving/kinds.scala index 31cfaff..2e7d67b 100644 --- a/modules/deriving/src/main/scala/shapeless3/deriving/kinds.scala +++ b/modules/deriving/src/main/scala/shapeless3/deriving/kinds.scala @@ -23,111 +23,137 @@ import scala.compiletime.* import scala.compiletime.ops.int.S import scala.deriving.* -object K0: - infix type of[M <: Mirror, O] = M { +trait Kind[Up <: AnyKind, Tup <: AnyKind, Mono[_ <: Up], Head[_ <: Tup] <: Up, Tail[_ <: Tup] <: Up]: + self => + + type of[M <: Mirror, O <: Up] = M { type MirroredType = O - type MirroredMonoType = O - type MirroredElemTypes <: Tuple + type MirroredMonoType = Mono[O] + type MirroredElemTypes <: Tup } - type Kind[M <: Mirror, O] = (M of O) { type Kind = K0.type } - type Generic[O] = Kind[Mirror, O] - type ProductGeneric[O] = Kind[Mirror.Product, O] - type CoproductGeneric[O] = Kind[Mirror.Sum, O] + type Kind[M <: Mirror, O <: Up] = (M of O) { type Kind = self.type } + type Generic[O <: Up] = Kind[Mirror, O] + type ProductGeneric[O <: Up] = Kind[Mirror.Product, O] + type CoproductGeneric[O <: Up] = Kind[Mirror.Sum, O] object Generic: - given fromMirror[M <: Mirror, O](using m: M of O): Kind[m.type, O] = m.asInstanceOf + given fromMirror[M <: Mirror, O <: Up](using m: M of O): Kind[m.type, O] = m.asInstanceOf - def Generic[O](using gen: Generic[O]): gen.type = gen - def ProductGeneric[O](using gen: ProductGeneric[O]): gen.type = gen - def CoproductGeneric[O](using gen: CoproductGeneric[O]): gen.type = gen + def Generic[O <: Up](using gen: Generic[O]): gen.type = gen + def ProductGeneric[O <: Up](using gen: ProductGeneric[O]): gen.type = gen + def CoproductGeneric[O <: Up](using gen: CoproductGeneric[O]): gen.type = gen - type Instances[F[_], T] = ErasedInstances[K0.type, F[T]] - type ProductInstances[F[_], T] = ErasedProductInstances[K0.type, F[T]] - type CoproductInstances[F[_], T] = ErasedCoproductInstances[K0.type, F[T]] + type Instances[F[_ <: Up], T <: Up] = ErasedInstances[self.type, F[T]] + type ProductInstances[F[_ <: Up], T <: Up] = ErasedProductInstances[self.type, F[T]] + type CoproductInstances[F[_ <: Up], T <: Up] = ErasedCoproductInstances[self.type, F[T]] - type InstancesOf[F[_]] = [T] =>> Instances[F, T] - type ProductInstancesOf[F[_]] = [T] =>> ProductInstances[F, T] - type CoproductInstancesOf[F[_]] = [T] =>> CoproductInstances[F, T] + type InstancesOf[F[_ <: Up]] = [T <: Up] =>> Instances[F, T] + type ProductInstancesOf[F[_ <: Up]] = [T <: Up] =>> ProductInstances[F, T] + type CoproductInstancesOf[F[_ <: Up]] = [T <: Up] =>> CoproductInstances[F, T] - def Instances[F[_], T](using inst: Instances[F, T]): inst.type = inst - def ProductInstances[F[_], T](using inst: ProductInstances[F, T]): inst.type = inst - def CoproductInstances[F[_], T](using inst: CoproductInstances[F, T]): inst.type = inst + def Instances[F[_ <: Up], T <: Up](using inst: Instances[F, T]): inst.type = inst + def ProductInstances[F[_ <: Up], T <: Up](using inst: ProductInstances[F, T]): inst.type = inst + def CoproductInstances[F[_ <: Up], T <: Up](using inst: CoproductInstances[F, T]): inst.type = inst - type IndexOf[E, X] = IndexOf0[E, X, 0] + type LiftP[F[_ <: Up], T <: Tup] <: Tuple = Mono[T] match + case _ *: _ => F[Head[T]] *: LiftP[F, Tail[T]] + case _ => EmptyTuple - type IndexOf0[E, X, I <: Int] <: Int = X match - case EmptyTuple => -1 - case x *: xs => - x match - case E => I - case _ => IndexOf0[E, xs, S[I]] + inline given mkInstances[F[_ <: Up], T <: Up](using gen: Mirror of T): Instances[F, T] = + inline gen match + case given (Mirror.Product of T) => mkProductInstances[F, T] + case given (Mirror.Sum of T) => mkCoproductInstances[F, T] - type Head[T] = T match - case h *: t => h - type Tail[T] = T match - case h *: t => t + inline given mkProductInstances[F[_ <: Up], T <: Up](using + gen: Mirror.Product of T + ): ProductInstances[F, T] = + ErasedProductInstances[self.type, F[T], LiftP[F, gen.MirroredElemTypes]](gen) - type LiftP[F[_], T] <: Tuple = - T match - case _ *: _ => F[Head[T]] *: LiftP[F, Tail[T]] - case _ => EmptyTuple + inline given mkCoproductInstances[F[_ <: Up], T <: Up](using + gen: Mirror.Sum of T + ): CoproductInstances[F, T] = + ErasedCoproductInstances[self.type, F[T], LiftP[F, gen.MirroredElemTypes]](gen) /** * Summon the first given instance `F[U]` from the tuple `T`. Remaining elements of `T` may or may not have an * instance of `F`. */ - inline def summonFirst[F[_], T]: F[Any] = - Kinds.summonFirst[LiftP[F, T]].asInstanceOf[F[Any]] - - @deprecated("Use summonFirst instead", "3.2.0") - transparent inline def summonFirst0[T]: Any = - Kinds.summonFirst[T] + inline def summonFirst[F[_ <: Up], T <: Tup]: F[Up] = + Kinds.summonFirst[LiftP[F, T]].asInstanceOf /** * Summon the only given instance `F[U]` from the tuple `T`. Remaining elements of `T` are guaranteed to not have an * instance of `F`. */ - inline def summonOnly[F[_], T]: F[Any] = - Kinds.summonOnly[LiftP[F, T]].asInstanceOf[F[Any]] + inline def summonOnly[F[_ <: Up], T <: Tup]: F[Up] = + Kinds.summonOnly[LiftP[F, T]].asInstanceOf /** Ensure that no element of the tuple `T` has an instance of `F`. */ - inline def summonNone[F[_], T]: Unit = + inline def summonNone[F[_ <: Up], T <: Tup]: Unit = Kinds.summonNone[LiftP[F, T]] + extension [F[_ <: Up], T <: Up](gen: Generic[T]) + inline def derive( + f: => (ProductGeneric[T] & gen.type) ?=> F[T], + g: => (CoproductGeneric[T] & gen.type) ?=> F[T] + ): F[T] = inline gen match + case p: ProductGeneric[T] => f(using p.asInstanceOf) + case c: CoproductGeneric[T] => g(using c.asInstanceOf) + + extension [T <: Up](gen: CoproductGeneric[T]) + inline def withFirst[F[_ <: Up], R](f: [t <: T] => F[t] => R): R = + f(summonFirst[F, gen.MirroredElemTypes].asInstanceOf) + inline def withOnly[F[_ <: Up], R](f: [t <: T] => F[t] => R): R = + f(summonOnly[F, gen.MirroredElemTypes].asInstanceOf) + + extension [F[_ <: Up], T <: Up](inst: Instances[F, T]) + inline def mapK[G[_ <: Up]](f: [t <: Up] => F[t] => G[t]): Instances[G, T] = + inst.erasedMapK(f.asInstanceOf).asInstanceOf + inline def widen[G[t <: Up] >: F[t]]: Instances[G, T] = + inst.asInstanceOf + + extension [F[_ <: Up], T <: Up](inst: ProductInstances[F, T]) + inline def mapK[G[_ <: Up]](f: [t <: Up] => F[t] => G[t]): ProductInstances[G, T] = + inst.erasedMapK(f.asInstanceOf).asInstanceOf + inline def widen[G[t <: Up] >: F[t]]: ProductInstances[G, T] = + inst.asInstanceOf + + extension [F[_ <: Up], T <: Up](inst: CoproductInstances[F, T]) + inline def mapK[G[_ <: Up]](f: [t <: Up] => F[t] => G[t]): CoproductInstances[G, T] = + inst.erasedMapK(f.asInstanceOf).asInstanceOf + inline def widen[G[t <: Up] >: F[t]]: CoproductInstances[G, T] = + inst.asInstanceOf + +object K0 extends Kind[Any, Tuple, Id, Kinds.Head, Kinds.Tail]: + type IndexOf[E, X] = IndexOf0[E, X, 0] + type IndexOf0[E, X, I <: Int] <: Int = X match + case EmptyTuple => -1 + case x *: xs => + x match + case E => I + case _ => IndexOf0[E, xs, S[I]] + + @deprecated("Use summonFirst instead", "3.2.0") + transparent inline def summonFirst0[T]: Any = Kinds.summonFirst[T] + extension [T](gen: ProductGeneric[T]) inline def toRepr(o: T): gen.MirroredElemTypes = Tuple.fromProduct(o.asInstanceOf).asInstanceOf[gen.MirroredElemTypes] - inline def fromRepr(r: gen.MirroredElemTypes): T = gen.fromProduct(r.asInstanceOf) + inline def fromRepr(r: gen.MirroredElemTypes): T = + gen.fromProduct(r.asInstanceOf) extension [T](gen: CoproductGeneric[T]) inline def toRepr(o: T): Union[gen.MirroredElemTypes] = o.asInstanceOf inline def fromRepr(r: Union[gen.MirroredElemTypes]): T = r.asInstanceOf - inline def withFirst[F[_], R](f: [t <: T] => F[t] => R): R = f(summonFirst[F, gen.MirroredElemTypes].asInstanceOf) - inline def withOnly[F[_], R](f: [t <: T] => F[t] => R): R = f(summonOnly[F, gen.MirroredElemTypes].asInstanceOf) - - extension [F[_], T](gen: Generic[T]) - inline def derive( - f: => (ProductGeneric[T] & gen.type) ?=> F[T], - g: => (CoproductGeneric[T] & gen.type) ?=> F[T] - ): F[T] = - inline gen match - case p: ProductGeneric[T] => f(using p.asInstanceOf) - case c: CoproductGeneric[T] => g(using c.asInstanceOf) extension [F[_], T](inst: Instances[F, T]) - inline def mapK[G[_]](f: [t] => F[t] => G[t]): Instances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def map(x: T)(f: [t] => (F[t], t) => t): T = inst.erasedMap(x)(f.asInstanceOf).asInstanceOf - inline def widen[G[t] >: F[t]]: Instances[G, T] = - inst.asInstanceOf inline def traverse[G[_]](x: T)(map: MapF[G])(pure: Pure[G])(ap: Ap[G])(f: [t] => (F[t], t) => G[t]): G[T] = inst.erasedTraverse(x)(map)(pure)(ap)(f.asInstanceOf).asInstanceOf extension [F[_], T](inst: ProductInstances[F, T]) - inline def mapK[G[_]](f: [t] => F[t] => G[t]): ProductInstances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def construct(f: [t] => F[t] => t): T = inst.erasedConstruct(f.asInstanceOf).asInstanceOf inline def constructA[G[_]](f: [t] => F[t] => G[t])(pure: Pure[G], map: MapF[G], ap: Ap[G]): G[T] = @@ -148,12 +174,8 @@ object K0: inst.erasedFoldRight2(x, y)(i)(f.asInstanceOf).asInstanceOf inline def project[R](t: T)(p: Int)(f: [t] => (F[t], t) => R): R = inst.erasedProject(t)(p)(f.asInstanceOf).asInstanceOf - inline def widen[G[t] >: F[t]]: ProductInstances[G, T] = - inst.asInstanceOf extension [F[_], T](inst: CoproductInstances[F, T]) - inline def mapK[G[_]](f: [t <: T] => F[t] => G[t]): CoproductInstances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def inject[R](p: Int)(f: [t <: T] => F[t] => R): R = inst.erasedInject(p)(f.asInstanceOf).asInstanceOf @deprecated("use inject", "3.0.2") @@ -165,122 +187,38 @@ object K0: inst.erasedFold2(x, y)(a.asInstanceOf)(f.asInstanceOf).asInstanceOf inline def fold2[R](x: T, y: T)(g: (Int, Int) => R)(f: [t <: T] => (F[t], t, t) => R): R = inst.erasedFold2f(x, y)(g.asInstanceOf)(f.asInstanceOf).asInstanceOf - inline def widen[G[t] >: F[t]]: CoproductInstances[G, T] = - inst.asInstanceOf - - inline given mkInstances[F[_], T](using gen: Mirror of T): Instances[F, T] = - inline gen match - case given (Mirror.Product of T) => mkProductInstances[F, T] - case given (Mirror.Sum of T) => mkCoproductInstances[F, T] - - inline given mkProductInstances[F[_], T](using gen: Mirror.Product of T): ProductInstances[F, T] = - ErasedProductInstances[K0.type, F[T], LiftP[F, gen.MirroredElemTypes]](gen) - - inline given mkCoproductInstances[F[_], T](using gen: Mirror.Sum of T): CoproductInstances[F, T] = - ErasedCoproductInstances[K0.type, F[T], LiftP[F, gen.MirroredElemTypes]](gen): CoproductInstances[F, T] - -object K1: - infix type of[M <: Mirror, O[_]] = M { - type MirroredType[X] = O[X] - type MirroredMonoType = O[Any] - type MirroredElemTypes[_] <: Tuple - } - type Kind[M <: Mirror, O[_]] = (M of O) { type Kind = K1.type } - type Generic[O[_]] = Kind[Mirror, O] - type ProductGeneric[O[_]] = Kind[Mirror.Product, O] - type CoproductGeneric[O[_]] = Kind[Mirror.Sum, O] - - object Generic: - given fromMirror[M <: Mirror, O[_]](using m: M of O): Kind[m.type, O] = m.asInstanceOf - - def Generic[O[_]](using gen: Generic[O]): gen.type = gen - def ProductGeneric[O[_]](using gen: ProductGeneric[O]): gen.type = gen - def CoproductGeneric[O[_]](using gen: CoproductGeneric[O]): gen.type = gen - - type Instances[F[_[_]], T[_]] = ErasedInstances[K1.type, F[T]] - type ProductInstances[F[_[_]], T[_]] = ErasedProductInstances[K1.type, F[T]] - type CoproductInstances[F[_[_]], T[_]] = ErasedCoproductInstances[K1.type, F[T]] - - type InstancesOf[F[_[_]]] = [T[_]] =>> Instances[F, T] - type ProductInstancesOf[F[_[_]]] = [T[_]] =>> ProductInstances[F, T] - type CoproductInstancesOf[F[_[_]]] = [T[_]] =>> CoproductInstances[F, T] - - def Instances[F[_[_]], T[_]](using inst: Instances[F, T]): inst.type = inst - def ProductInstances[F[_[_]], T[_]](using inst: ProductInstances[F, T]): inst.type = inst - def CoproductInstances[F[_[_]], T[_]](using inst: CoproductInstances[F, T]): inst.type = inst - - type Head[T <: [X] =>> Any, A] = T[A] match - case h *: t => h - type Tail[T <: [X] =>> Any, A] = T[A] match - case h *: t => t - - type LiftP[F[_[_]], T <: [X] =>> Any] <: Tuple = - T[Any] match - case _ *: _ => F[[X] =>> Head[T, X]] *: LiftP[F, [X] =>> Tail[T, X]] - case _ => EmptyTuple - - /** - * Summon the first given instance `F[U]` from the tuple `T`. Remaining elements of `T` may or may not have an - * instance of `F`. - */ - inline def summonFirst[F[_[_]], T[_]]: F[[_] =>> Any] = - Kinds.summonFirst[LiftP[F, T]].asInstanceOf[F[[_] =>> Any]] +object K1 + extends Kind[ + [_] =>> Any, + [_] =>> Tuple, + [t[_]] =>> t[Any], + [t[_]] =>> [a] =>> Kinds.Head[t[a]], + [t[_]] =>> [a] =>> Kinds.Tail[t[a]] + ]: @deprecated("Use summonFirst instead", "3.2.0") - transparent inline def summonFirst0[T]: Any = - Kinds.summonFirst[T] - - /** - * Summon the only given instance `F[U]` from the tuple `T`. Remaining elements of `T` are guaranteed to not have an - * instance of `F`. - */ - inline def summonOnly[F[_[_]], T[_]]: F[[_] =>> Any] = - Kinds.summonOnly[LiftP[F, T]].asInstanceOf[F[[_] =>> Any]] - - /** Ensure that no element of the tuple `T` has an instance of `F`. */ - inline def summonNone[F[_[_]], T[_]]: Unit = - Kinds.summonNone[LiftP[F, T]] + transparent inline def summonFirst0[T]: Any = Kinds.summonFirst[T] extension [T[_], A](gen: ProductGeneric[T]) inline def toRepr(o: T[A]): gen.MirroredElemTypes[A] = Tuple.fromProduct(o.asInstanceOf).asInstanceOf[gen.MirroredElemTypes[A]] - inline def fromRepr(r: gen.MirroredElemTypes[A]): T[A] = gen.fromProduct(r.asInstanceOf).asInstanceOf[T[A]] + inline def fromRepr(r: gen.MirroredElemTypes[A]): T[A] = + gen.fromProduct(r.asInstanceOf).asInstanceOf[T[A]] extension [T[_], A](gen: CoproductGeneric[T]) inline def toRepr(o: T[A]): Union[gen.MirroredElemTypes[A]] = o.asInstanceOf inline def fromRepr(r: Union[gen.MirroredElemTypes[A]]): T[A] = r.asInstanceOf - inline def withFirst[F[_[_]], R](f: [t[x] <: T[x]] => F[t] => R): R = f( - summonFirst[F, gen.MirroredElemTypes].asInstanceOf - ) - inline def withOnly[F[_[_]], R](f: [t[x] <: T[x]] => F[t] => R): R = f( - summonOnly[F, gen.MirroredElemTypes].asInstanceOf - ) - - extension [F[_[_]], T[_]](gen: Generic[T]) - inline def derive( - f: => (ProductGeneric[T] & gen.type) ?=> F[T], - g: => (CoproductGeneric[T] & gen.type) ?=> F[T] - ): F[T] = - inline gen match - case p: ProductGeneric[T] => f(using p.asInstanceOf) - case c: CoproductGeneric[T] => g(using c.asInstanceOf) extension [F[_[_]], T[_]](inst: Instances[F, T]) - inline def mapK[G[_[_]]](f: [t[_]] => F[t] => G[t]): Instances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def map[A, R](x: T[A])(f: [t[_]] => (F[t], t[A]) => t[R]): T[R] = inst.erasedMap(x)(f.asInstanceOf).asInstanceOf - inline def widen[G[t[_]] >: F[t]]: Instances[G, T] = - inst.asInstanceOf inline def traverse[A, G[_], R](x: T[A])(map: MapF[G])(pure: Pure[G])(ap: Ap[G])( f: [t[_]] => (F[t], t[A]) => G[t[R]] ): G[T[R]] = inst.erasedTraverse(x)(map)(pure)(ap)(f.asInstanceOf).asInstanceOf extension [F[_[_]], T[_]](inst: ProductInstances[F, T]) - inline def mapK[G[_[_]]](f: [t[_]] => F[t] => G[t]): ProductInstances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def construct[R](f: [t[_]] => F[t] => t[R]): T[R] = inst.erasedConstruct(f.asInstanceOf).asInstanceOf inline def constructA[G[_], R](f: [t[_]] => F[t] => G[t[R]])(pure: Pure[G], map: MapF[G], ap: Ap[G]): G[T[R]] = @@ -305,137 +243,46 @@ object K1: inst.erasedFoldRight2(x, y)(i)(f.asInstanceOf).asInstanceOf inline def project[A, R](t: T[A])(p: Int)(f: [t[_]] => (F[t], t[A]) => R): R = inst.erasedProject(t)(p)(f.asInstanceOf).asInstanceOf - inline def widen[G[t[_]] >: F[t]]: ProductInstances[G, T] = - inst.asInstanceOf extension [F[_[_]], T[_]](inst: CoproductInstances[F, T]) - inline def mapK[G[_[_]]](f: [t[x] <: T[x]] => F[t] => G[t]): CoproductInstances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def fold[A, R](x: T[A])(f: [t[x] <: T[x]] => (F[t], t[A]) => R): R = inst.erasedFold(x)(f.asInstanceOf).asInstanceOf inline def fold2[A, B, R](x: T[A], y: T[B])(a: => R)(f: [t[x] <: T[x]] => (F[t], t[A], t[B]) => R): R = inst.erasedFold2(x, y)(a.asInstanceOf)(f.asInstanceOf).asInstanceOf inline def fold2[A, B, R](x: T[A], y: T[B])(g: (Int, Int) => R)(f: [t[x] <: T[x]] => (F[t], t[A], t[B]) => R): R = inst.erasedFold2f(x, y)(g.asInstanceOf)(f.asInstanceOf).asInstanceOf - inline def widen[G[t[_]] >: F[t]]: CoproductInstances[G, T] = - inst.asInstanceOf - inline given mkInstances[F[_[_]], T[_]](using gen: Mirror of T): Instances[F, T] = - inline gen match - case given (Mirror.Product of T) => mkProductInstances[F, T] - case given (Mirror.Sum of T) => mkCoproductInstances[F, T] - - inline given mkProductInstances[F[_[_]], T[_]](using gen: Mirror.Product of T): ProductInstances[F, T] = - ErasedProductInstances[K1.type, F[T], LiftP[F, gen.MirroredElemTypes]](gen) - - inline given mkCoproductInstances[F[_[_]], T[_]](using gen: Mirror.Sum of T): CoproductInstances[F, T] = - ErasedCoproductInstances[K1.type, F[T], LiftP[F, gen.MirroredElemTypes]](gen) - -object K11: - infix type of[M <: Mirror, O[_[_]]] = M { - type MirroredType[X[_]] = O[X] - type MirroredMonoType = O[[_] =>> Any] - type MirroredElemTypes[_[_]] <: Tuple - } - - type Kind[M <: Mirror, O[_[_]]] = (M of O) { type Kind = K11.type } - type Generic[O[_[_]]] = Kind[Mirror, O] - type ProductGeneric[O[_[_]]] = Kind[Mirror.Product, O] - type CoproductGeneric[O[_[_]]] = Kind[Mirror.Sum, O] - - object Generic: - given fromMirror[M <: Mirror, O[_[_]]](using m: M of O): Kind[m.type, O] = m.asInstanceOf - - def Generic[O[_[_]]](using gen: Generic[O]): gen.type = gen - def ProductGeneric[O[_[_]]](using gen: ProductGeneric[O]): gen.type = gen - def CoproductGeneric[O[_[_]]](using gen: CoproductGeneric[O]): gen.type = gen - - type Instances[F[_[_[_]]], T[_[_]]] = ErasedInstances[K11.type, F[T]] - type ProductInstances[F[_[_[_]]], T[_[_]]] = ErasedProductInstances[K11.type, F[T]] - type CoproductInstances[F[_[_[_]]], T[_[_]]] = ErasedCoproductInstances[K11.type, F[T]] - - type InstancesOf[F[_[_[_]]]] = [T[_[_]]] =>> Instances[F, T] - type ProductInstancesOf[F[_[_[_]]]] = [T[_[_]]] =>> ProductInstances[F, T] - type CoproductInstancesOf[F[_[_[_]]]] = [T[_[_]]] =>> CoproductInstances[F, T] - - def Instances[F[_[_[_]]], T[_[_]]](using inst: Instances[F, T]): inst.type = inst - def ProductInstances[F[_[_[_]]], T[_[_]]](using inst: ProductInstances[F, T]): inst.type = inst - def CoproductInstances[F[_[_[_]]], T[_[_]]](using inst: CoproductInstances[F, T]): inst.type = inst +object K11 + extends Kind[ + [_[_]] =>> Any, + [_[_]] =>> Tuple, + [t[_[_]]] =>> t[[_] =>> Any], + [t[_[_]]] =>> [a[_]] =>> Kinds.Head[t[a]], + [t[_[_]]] =>> [a[_]] =>> Kinds.Tail[t[a]] + ]: type Id[t] = [f[_]] =>> f[t] type Const[c] = [f[_]] =>> c - type Head[T <: [G[_]] =>> Any, A[_]] = T[A] match - case h *: t => h - type Tail[T <: [G[_]] =>> Any, A[_]] = T[A] match - case h *: t => t - - type LiftP[F[_[_[_]]], T <: [G[_]] =>> Any] <: Tuple = - T[Option] match - case _ *: _ => F[[A[_]] =>> Head[T, A]] *: LiftP[F, [A[_]] =>> Tail[T, A]] - case _ => EmptyTuple - - /** - * Summon the first given instance `F[U]` from the tuple `T`. Remaining elements of `T` may or may not have an - * instance of `F`. - */ - inline def summonFirst[F[_[_[_]]], T[_[_]]]: F[[_[_]] =>> Any] = - Kinds.summonFirst[LiftP[F, T]].asInstanceOf[F[[_[_]] =>> Any]] - - @deprecated("Use summonFirst instead", "3.2.0") - transparent inline def summonFirst0[T]: Any = - Kinds.summonFirst[T] - - /** - * Summon the only given instance `F[U]` from the tuple `T`. Remaining elements of `T` are guaranteed to not have an - * instance of `F`. - */ - inline def summonOnly[F[_[_[_]]], T[_[_]]]: F[[_[_]] =>> Any] = - Kinds.summonOnly[LiftP[F, T]].asInstanceOf[F[[_[_]] =>> Any]] - - /** Ensure that no element of the tuple `T` has an instance of `F`. */ - inline def summonNone[F[_[_[_]]], T[_[_]]]: Unit = - Kinds.summonNone[LiftP[F, T]] - extension [T[_[_]], A[_]](gen: ProductGeneric[T]) inline def toRepr(o: T[A]): gen.MirroredElemTypes[A] = Tuple.fromProduct(o.asInstanceOf).asInstanceOf[gen.MirroredElemTypes[A]] - inline def fromRepr(r: gen.MirroredElemTypes[A]): T[A] = gen.fromProduct(r.asInstanceOf).asInstanceOf[T[A]] + inline def fromRepr(r: gen.MirroredElemTypes[A]): T[A] = + gen.fromProduct(r.asInstanceOf).asInstanceOf[T[A]] extension [T[_[_]], A[_]](gen: CoproductGeneric[T]) inline def toRepr(o: T[A]): Union[gen.MirroredElemTypes[A]] = o.asInstanceOf inline def fromRepr(r: Union[gen.MirroredElemTypes[A]]): T[A] = r.asInstanceOf - inline def withFirst[F[_[_[_]]], R](f: [t[x[_]] <: T[x]] => F[t] => R): R = f( - summonFirst[F, gen.MirroredElemTypes].asInstanceOf - ) - inline def withOnly[F[_[_[_]]], R](f: [t[x[_]] <: T[x]] => F[t] => R): R = f( - summonOnly[F, gen.MirroredElemTypes].asInstanceOf - ) - - extension [F[_[_[_]]], T[_[_]]](gen: Generic[T]) - inline def derive( - f: => (ProductGeneric[T] & gen.type) ?=> F[T], - g: => (CoproductGeneric[T] & gen.type) ?=> F[T] - ): F[T] = - inline gen match - case p: ProductGeneric[T] => f(using p.asInstanceOf) - case c: CoproductGeneric[T] => g(using c.asInstanceOf) extension [F[_[_[_]]], T[_[_]]](inst: Instances[F, T]) - inline def mapK[G[_[_[_]]]](f: [t[_[_]]] => F[t] => G[t]): Instances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def map[A[_], R[_]](x: T[A])(f: [t[_[_]]] => (F[t], t[A]) => t[R]): T[R] = inst.erasedMap(x)(f.asInstanceOf).asInstanceOf - inline def widen[G[t[_[_]]] >: F[t]]: Instances[G, T] = - inst.asInstanceOf inline def traverse[A[_], G[_], R[_]](x: T[A])(map: MapF[G])(pure: Pure[G])(ap: Ap[G])( f: [t[_[_]]] => (F[t], t[A]) => G[t[R]] ): G[T[R]] = inst.erasedTraverse(x)(map)(pure)(ap)(f.asInstanceOf).asInstanceOf extension [F[_[_[_]]], T[_[_]]](inst: ProductInstances[F, T]) - inline def mapK[G[_[_[_]]]](f: [t[_[_]]] => F[t] => G[t]): ProductInstances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def construct[R[_]](f: [t[_[_]]] => F[t] => t[R]): T[R] = inst.erasedConstruct(f.asInstanceOf).asInstanceOf inline def constructA[G[_], R[_]]( @@ -462,12 +309,8 @@ object K11: inst.erasedFoldRight2(x, y)(i)(f.asInstanceOf).asInstanceOf inline def project[A[_], R](t: T[A])(p: Int)(f: [t[_[_]]] => (F[t], t[A]) => R): R = inst.erasedProject(t)(p)(f.asInstanceOf).asInstanceOf - inline def widen[G[t[_[_]]] >: F[t]]: ProductInstances[G, T] = - inst.asInstanceOf extension [F[_[_[_]]], T[_[_]]](inst: CoproductInstances[F, T]) - inline def mapK[G[_[_[_]]]](f: [t[x[_]] <: T[x]] => F[t] => G[t]): CoproductInstances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def fold[A[_], R](x: T[A])(f: [t[x[_]] <: T[x]] => (F[t], t[A]) => R): R = inst.erasedFold(x)(f.asInstanceOf).asInstanceOf inline def fold2[A[_], B[_], R](x: T[A], y: T[B])(a: => R)(f: [t[x[_]] <: T[x]] => (F[t], t[A], t[B]) => R): R = @@ -476,126 +319,42 @@ object K11: f: [t[x[_]] <: T[x]] => (F[t], t[A], t[B]) => R ): R = inst.erasedFold2f(x, y)(g.asInstanceOf)(f.asInstanceOf).asInstanceOf - inline def widen[G[t[_[_]]] >: F[t]]: CoproductInstances[G, T] = - inst.asInstanceOf - inline given mkInstances[F[_[_[_]]], T[_[_]]](using gen: Mirror of T): Instances[F, T] = - inline gen match - case given (Mirror.Product of T) => mkProductInstances[F, T] - case given (Mirror.Sum of T) => mkCoproductInstances[F, T] - - inline given mkProductInstances[F[_[_[_]]], T[_[_]]](using gen: Mirror.Product of T): ProductInstances[F, T] = - ErasedProductInstances[K11.type, F[T], LiftP[F, gen.MirroredElemTypes]](gen) - - inline given mkCoproductInstances[F[_[_[_]]], T[_[_]]](using gen: Mirror.Sum of T): CoproductInstances[F, T] = - ErasedCoproductInstances[K11.type, F[T], LiftP[F, gen.MirroredElemTypes]](gen) - -object K2: - infix type of[M <: Mirror, O[_, _]] = M { - type MirroredType[X, Y] = O[X, Y] - type MirroredMonoType = O[Any, Any] - type MirroredElemTypes[_, _] <: Tuple - } - - type Kind[M <: Mirror, O[_, _]] = (M of O) { type Kind = K2.type } - type Generic[O[_, _]] = Kind[Mirror, O] - type ProductGeneric[O[_, _]] = Kind[Mirror.Product, O] - type CoproductGeneric[O[_, _]] = Kind[Mirror.Sum, O] - - object Generic: - given fromMirror[M <: Mirror, O[_, _]](using m: M of O): Kind[m.type, O] = m.asInstanceOf - - def Generic[O[_, _]](using gen: Generic[O]): gen.type = gen - def ProductGeneric[O[_, _]](using gen: ProductGeneric[O]): gen.type = gen - def CoproductGeneric[O[_, _]](using gen: CoproductGeneric[O]): gen.type = gen - - type Instances[F[_[_, _]], T[_, _]] = ErasedInstances[K2.type, F[T]] - type ProductInstances[F[_[_, _]], T[_, _]] = ErasedProductInstances[K2.type, F[T]] - type CoproductInstances[F[_[_, _]], T[_, _]] = ErasedCoproductInstances[K2.type, F[T]] - - type InstancesOf[F[_[_, _]]] = [T[_, _]] =>> Instances[F, T] - type ProductInstancesOf[F[_[_, _]]] = [T[_, _]] =>> ProductInstances[F, T] - type CoproductInstancesOf[F[_[_, _]]] = [T[_, _]] =>> CoproductInstances[F, T] - - def Instances[F[_[_, _]], T[_, _]](using inst: Instances[F, T]): inst.type = inst - def ProductInstances[F[_[_, _]], T[_, _]](using inst: ProductInstances[F, T]): inst.type = inst - def CoproductInstances[F[_[_, _]], T[_, _]](using inst: CoproductInstances[F, T]): inst.type = inst +object K2 + extends Kind[ + [_, _] =>> Any, + [_, _] =>> Tuple, + [t[_, _]] =>> t[Any, Any], + [t[_, _]] =>> [a, b] =>> Kinds.Head[t[a, b]], + [t[_, _]] =>> [a, b] =>> Kinds.Tail[t[a, b]] + ]: type Id1[t, u] = t type Id2[t, u] = u type Const[c] = [t, u] =>> c - type Head[T <: [X, Y] =>> Any, A, B] = T[A, B] match - case h *: t => h - type Tail[T <: [X, Y] =>> Any, A, B] = T[A, B] match - case h *: t => t - - type LiftP[F[_[_, _]], T <: [X, Y] =>> Any] <: Tuple = - T[Any, Any] match - case _ *: _ => F[[X, Y] =>> Head[T, X, Y]] *: LiftP[F, [X, Y] =>> Tail[T, X, Y]] - case _ => EmptyTuple - - /** - * Summon the first given instance `F[U]` from the tuple `T`. Remaining elements of `T` may or may not have an - * instance of `F`. - */ - inline def summonFirst[F[_[_, _]], T[_, _]]: F[[_, _] =>> Any] = - Kinds.summonFirst[LiftP[F, T]].asInstanceOf[F[[_, _] =>> Any]] - @deprecated("Use summonFirst instead", "3.2.0") - transparent inline def summonFirst0[T]: Any = - Kinds.summonFirst[T] - - /** - * Summon the only given instance `F[U]` from the tuple `T`. Remaining elements of `T` are guaranteed to not have an - * instance of `F`. - */ - inline def summonOnly[F[_[_, _]], T[_, _]]: F[[_, _] =>> Any] = - Kinds.summonOnly[LiftP[F, T]].asInstanceOf[F[[_, _] =>> Any]] - - /** Ensure that no element of the tuple `T` has an instance of `F`. */ - inline def summonNone[F[_[_, _]], T[_, _], U[_, _]]: Unit = - Kinds.summonNone[LiftP[F, T]] + transparent inline def summonFirst0[T]: Any = Kinds.summonFirst[T] extension [T[_, _], A, B](gen: ProductGeneric[T]) inline def toRepr(o: T[A, B]): gen.MirroredElemTypes[A, B] = Tuple.fromProduct(o.asInstanceOf).asInstanceOf[gen.MirroredElemTypes[A, B]] - inline def fromRepr(r: gen.MirroredElemTypes[A, B]): T[A, B] = gen.fromProduct(r.asInstanceOf).asInstanceOf[T[A, B]] + inline def fromRepr(r: gen.MirroredElemTypes[A, B]): T[A, B] = + gen.fromProduct(r.asInstanceOf).asInstanceOf[T[A, B]] extension [T[_, _], A, B](gen: CoproductGeneric[T]) inline def toRepr(o: T[A, B]): Union[gen.MirroredElemTypes[A, B]] = o.asInstanceOf inline def fromRepr(r: Union[gen.MirroredElemTypes[A, B]]): T[A, B] = r.asInstanceOf - inline def withFirst[F[_[_, _]], R](f: [t[x, y] <: T[x, y]] => F[t] => R): R = f( - summonFirst[F, gen.MirroredElemTypes].asInstanceOf - ) - inline def withOnly[F[_[_, _]], R](f: [t[x, y] <: T[x, y]] => F[t] => R): R = f( - summonOnly[F, gen.MirroredElemTypes].asInstanceOf - ) - - extension [F[_[_, _]], T[_, _]](gen: Generic[T]) - inline def derive( - f: => (ProductGeneric[T] & gen.type) ?=> F[T], - g: => (CoproductGeneric[T] & gen.type) ?=> F[T] - ): F[T] = - inline gen match - case p: ProductGeneric[T] => f(using p.asInstanceOf) - case c: CoproductGeneric[T] => g(using c.asInstanceOf) extension [F[_[_, _]], T[_, _]](inst: Instances[F, T]) - inline def mapK[G[_[_, _]]](f: [t[_, _]] => F[t] => G[t]): Instances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def map[A, B, R, S](x: T[A, B])(f: [t[_, _]] => (F[t], t[A, B]) => t[R, S]): T[R, S] = inst.erasedMap(x)(f.asInstanceOf).asInstanceOf - inline def widen[G[t[_, _]] >: F[t]]: Instances[G, T] = - inst.asInstanceOf inline def traverse[A, B, G[_], R, S](x: T[A, B])(map: MapF[G])(pure: Pure[G])(ap: Ap[G])( f: [t[_, _]] => (F[t], t[A, B]) => G[t[R, S]] ): G[T[R, S]] = inst.erasedTraverse(x)(map)(pure)(ap)(f.asInstanceOf).asInstanceOf extension [F[_[_, _]], T[_, _]](inst: ProductInstances[F, T]) - inline def mapK[G[_[_, _]]](f: [t[_, _]] => F[t] => G[t]): ProductInstances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def construct[R, S](f: [t[_, _]] => F[t] => t[R, S]): T[R, S] = inst.erasedConstruct(f.asInstanceOf).asInstanceOf inline def constructA[G[_], R, S]( @@ -624,12 +383,8 @@ object K2: inst.erasedFoldRight2(x, y)(i)(f.asInstanceOf).asInstanceOf inline def project[A, B, R](t: T[A, B])(p: Int)(f: [t[_, _]] => (F[t], t[A, B]) => R): R = inst.erasedProject(t)(p)(f.asInstanceOf).asInstanceOf - inline def widen[G[t[_, _]] >: F[t]]: ProductInstances[G, T] = - inst.asInstanceOf extension [F[_[_, _]], T[_, _]](inst: CoproductInstances[F, T]) - inline def mapK[G[_[_, _]]](f: [t[x, y] <: T[x, y]] => F[t] => G[t]): CoproductInstances[G, T] = - inst.erasedMapK(f.asInstanceOf).asInstanceOf inline def fold[A, B, R](x: T[A, B])(f: [t[x, y] <: T[x, y]] => (F[t], t[A, B]) => R): R = inst.erasedFold(x)(f.asInstanceOf).asInstanceOf inline def fold2[A, B, C, D, R](x: T[A, B], y: T[C, D])(a: => R)( @@ -640,16 +395,3 @@ object K2: f: [t[x, y] <: T[x, y]] => (F[t], t[A, B], t[C, D]) => R ): R = inst.erasedFold2f(x, y)(g.asInstanceOf)(f.asInstanceOf).asInstanceOf - inline def widen[G[t[_, _]] >: F[t]]: CoproductInstances[G, T] = - inst.asInstanceOf - - inline given mkInstances[F[_[_, _]], T[_, _]](using gen: Mirror of T): Instances[F, T] = - inline gen match - case given (Mirror.Product of T) => mkProductInstances[F, T] - case given (Mirror.Sum of T) => mkCoproductInstances[F, T] - - inline given mkProductInstances[F[_[_, _]], T[_, _]](using gen: Mirror.Product of T): ProductInstances[F, T] = - ErasedProductInstances[K2.type, F[T], LiftP[F, gen.MirroredElemTypes]](gen) - - inline given mkCoproductInstances[F[_[_, _]], T[_, _]](using gen: Mirror.Sum of T): CoproductInstances[F, T] = - ErasedCoproductInstances[K2.type, F[T], LiftP[F, gen.MirroredElemTypes]](gen)