From 9c39c492d8e0a999f0eebedea4322296d76ad161 Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Wed, 21 Aug 2024 12:19:12 +0300 Subject: [PATCH 1/3] Add K21 test example with BifunctorK type class (#224) * Add K21 for BifunctorK * Add tests for BifunctorK * Move K21 to tests --- .../test/scala/shapeless3/deriving/adts.scala | 8 ++ .../scala/shapeless3/deriving/deriving.scala | 13 +++ .../scala/shapeless3/deriving/kinds.scala | 82 +++++++++++++++++++ .../shapeless3/deriving/type-classes.scala | 34 +++++++- 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 modules/deriving/src/test/scala/shapeless3/deriving/kinds.scala diff --git a/modules/deriving/src/test/scala/shapeless3/deriving/adts.scala b/modules/deriving/src/test/scala/shapeless3/deriving/adts.scala index 9f22b98..acc340b 100644 --- a/modules/deriving/src/test/scala/shapeless3/deriving/adts.scala +++ b/modules/deriving/src/test/scala/shapeless3/deriving/adts.scala @@ -16,6 +16,8 @@ package shapeless3.deriving +import cats.data.{EitherK, Tuple2K} + // ADTs object adts: @@ -49,6 +51,12 @@ object adts: quantity: F[Int] ) derives FunctorK + enum Lattice[F[_], G[_]] derives BifunctorK: + case Top(value: F[Int]) + case Bot(value: G[Int]) + case Meet(value: Tuple2K[F, G, Int]) + case Join(value: EitherK[F, G, Int]) + sealed trait OptionD[T]: def fold: T = this match case Given(t) => t diff --git a/modules/deriving/src/test/scala/shapeless3/deriving/deriving.scala b/modules/deriving/src/test/scala/shapeless3/deriving/deriving.scala index 09dc54e..26f77fb 100644 --- a/modules/deriving/src/test/scala/shapeless3/deriving/deriving.scala +++ b/modules/deriving/src/test/scala/shapeless3/deriving/deriving.scala @@ -17,6 +17,7 @@ package shapeless3.deriving import cats.Eval +import cats.data.{EitherK, Tuple2K} import org.junit.Assert.* import org.junit.Test import shapeless3.deriving.adts.* @@ -255,6 +256,18 @@ class DerivationTests: val exp1 = HkCons(Some(42), HkCons(None, HkOne(Some(313)))) assert(FunctorK[HkNel].mapK(arg1)(OptionD.toOption) == exp1) + @Test + def bifunctorK(): Unit = + val bf = BifunctorK[Lattice] + val top = Lattice.Top[OptionD, OptionD](Given(100)) + val bot = Lattice.Bot[OptionD, OptionD](Default(0)) + val meet = Lattice.Meet[OptionD, OptionD](Tuple2K(Given(100), Default(0))) + val join = Lattice.Join[OptionD, OptionD](EitherK.left(Given(100))) + assert(bf.bimapK(top)(OptionD.fold, OptionD.toOption) == Lattice.Top[Id, Option](100)) + assert(bf.bimapK(bot)(OptionD.fold, OptionD.toOption) == Lattice.Bot[Id, Option](None)) + assert(bf.bimapK(meet)(OptionD.fold, OptionD.toOption) == Lattice.Meet[Id, Option](Tuple2K(100, None))) + assert(bf.bimapK(join)(OptionD.fold, OptionD.toOption) == Lattice.Join[Id, Option](EitherK.left(100))) + @Test def bifunctor(): Unit = val v0 = Bifunctor[ConsF] diff --git a/modules/deriving/src/test/scala/shapeless3/deriving/kinds.scala b/modules/deriving/src/test/scala/shapeless3/deriving/kinds.scala new file mode 100644 index 0000000..6cd23ed --- /dev/null +++ b/modules/deriving/src/test/scala/shapeless3/deriving/kinds.scala @@ -0,0 +1,82 @@ +package shapeless3.deriving + +import shapeless3.deriving.internals.Kinds + +import scala.Tuple.Union + +object K21 + 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] = [f[_], g[_]] =>> f[t] + type Id2[t] = [f[_], g[_]] =>> g[t] + type Const[c] = [t[_], u[_]] =>> c + + 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]] + + 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 + + extension [F[_[_[_], _[_]]], T[_[_], _[_]]](inst: Instances[F, T]) + 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 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 construct[R[_], S[_]](f: [t[_[_], _[_]]] => F[t] => t[R, S]): T[R, S] = + inst.erasedConstruct(f.asInstanceOf).asInstanceOf + inline def constructA[G[_], R[_], S[_]]( + f: [t[_[_], _[_]]] => F[t] => G[t[R, S]] + )(pure: Pure[G], map: MapF[G], ap: Ap[G]): G[T[R, S]] = + inst.erasedConstructA(f.asInstanceOf)(pure, map, ap).asInstanceOf + inline def constructM[G[_], R[_], S[_]]( + f: [t[_[_], _[_]]] => F[t] => G[t[R, S]] + )(pure: Pure[G], map: MapF[G], tailRecM: TailRecM[G]): G[T[R, S]] = + inst.erasedConstructM(f.asInstanceOf)(pure, map, tailRecM).asInstanceOf + inline def map2[A[_], B[_], C[_], D[_], R[_], S[_]](x: T[A, B], y: T[C, D])( + f: [t[_[_], _[_]]] => (F[t], t[A, B], t[B, C]) => t[R, S] + ): T[R, S] = + inst.erasedMap2(x, y)(f.asInstanceOf).asInstanceOf + inline def foldLeft[A[_], B[_], Acc](x: T[A, B])(i: Acc)( + f: [t[_[_], _[_]]] => (Acc, F[t], t[A, B]) => CompleteOr[Acc] + ): Acc = + inst.erasedFoldLeft(x)(i)(f.asInstanceOf).asInstanceOf + inline def foldLeft2[A[_], B[_], C[_], D[_], Acc](x: T[A, B], y: T[C, D])(i: Acc)( + f: [t[_[_], _[_]]] => (Acc, F[t], t[A, B], t[C, D]) => CompleteOr[Acc] + ): Acc = + inst.erasedFoldLeft2(x, y)(i)(f.asInstanceOf).asInstanceOf + inline def foldRight[A[_], B[_], Acc](x: T[A, B])(i: Acc)( + f: [t[_[_], _[_]]] => (F[t], t[A, B], Acc) => CompleteOr[Acc] + ): Acc = + inst.erasedFoldRight(x)(i)(f.asInstanceOf).asInstanceOf + inline def foldRight2[A[_], B[_], C[_], D[_], Acc](x: T[A, B], y: T[C, D])(i: Acc)( + f: [t[_[_], _[_]]] => (F[t], t[A, B], t[C, D], Acc) => CompleteOr[Acc] + ): Acc = + 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 + + extension [F[_[_[_], _[_]]], T[_[_], _[_]]](inst: CoproductInstances[F, T]) + inline def fold[A[_], B[_], R](x: T[A, B])(f: [t[a[_], b[_]] <: T[a, b]] => (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)( + f: [t[a[_], b[_]] <: T[a, b]] => (F[t], t[A, B], t[C, D]) => R + ): R = + inst.erasedFold2(x, y)(a.asInstanceOf)(f.asInstanceOf).asInstanceOf + inline def fold2[A[_], B[_], C[_], D[_], R](x: T[A, B], y: T[C, D])(g: (Int, Int) => R)( + f: [t[a[_], b[_]] <: T[a, b]] => (F[t], t[A, B], t[C, D]) => R + ): R = + inst.erasedFold2f(x, y)(g.asInstanceOf)(f.asInstanceOf).asInstanceOf diff --git a/modules/deriving/src/test/scala/shapeless3/deriving/type-classes.scala b/modules/deriving/src/test/scala/shapeless3/deriving/type-classes.scala index dd4b067..196d431 100644 --- a/modules/deriving/src/test/scala/shapeless3/deriving/type-classes.scala +++ b/modules/deriving/src/test/scala/shapeless3/deriving/type-classes.scala @@ -18,8 +18,8 @@ package shapeless3.deriving import scala.annotation.tailrec import scala.compiletime.* - import cats.Eval +import cats.data.{EitherK, Tuple2K} // Type classes @@ -342,6 +342,38 @@ object FunctorK: inline def derived[F[_[_]]](using gen: K11.Generic[F]): FunctorK[F] = functorKGen +trait BifunctorK[F[_[_], _[_]]]: + def bimapK[A[_], B[_], C[_], D[_]](fab: F[A, B])(f: A ~> C, g: B ~> D): F[C, D] + +object BifunctorK: + inline def apply[F[_[_], _[_]]](using bf: BifunctorK[F]): BifunctorK[F] = bf + + given [T]: BifunctorK[K21.Id1[T]] with + def bimapK[A[_], B[_], C[_], D[_]](at: A[T])(f: A ~> C, g: B ~> D): C[T] = f(at) + + given [T]: BifunctorK[K21.Id2[T]] with + def bimapK[A[_], B[_], C[_], D[_]](at: B[T])(f: A ~> C, g: B ~> D): D[T] = g(at) + + given [T]: BifunctorK[K21.Const[T]] with + def bimapK[A[_], B[_], C[_], D[_]](t: T)(f: A ~> C, g: B ~> D): T = t + + given [T]: BifunctorK[[f[_], g[_]] =>> Tuple2K[f, g, T]] with + def bimapK[A[_], B[_], C[_], D[_]](fab: Tuple2K[A, B, T])(f: A ~> C, g: B ~> D): Tuple2K[C, D, T] = + Tuple2K(f(fab.first), g(fab.second)) + + given [T]: BifunctorK[[f[_], g[_]] =>> EitherK[f, g, T]] with + def bimapK[A[_], B[_], C[_], D[_]](fab: EitherK[A, B, T])(f: A ~> C, g: B ~> D): EitherK[C, D, T] = + EitherK(fab.run match + case Left(a) => Left(f(a)) + case Right(b) => Right(g(b)) + ) + + given bifunctorKGen[F[_[_], _[_]]](using inst: => K21.Instances[BifunctorK, F]): BifunctorK[F] with + def bimapK[A[_], B[_], C[_], D[_]](fab: F[A, B])(f: A ~> C, g: B ~> D): F[C, D] = + inst.map(fab)([f[_[_], _[_]]] => (bf: BifunctorK[f], fab: f[A, B]) => bf.bimapK(fab)(f, g)) + + inline def derived[F[_[_], _[_]]: K21.Generic]: BifunctorK[F] = bifunctorKGen + case class Fix[S[_, _], A](unfix: S[A, Fix[S, A]]) trait Bifunctor[F[_, _]]: From 602dd45d132e792728302bc1706b71ad56eb947b Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Wed, 21 Aug 2024 12:37:29 +0300 Subject: [PATCH 2/3] Add ScalaDoc to kinds (#225) --- .../scala/shapeless3/deriving/deriving.scala | 2 +- .../shapeless3/deriving/internals/kinds.scala | 15 +- .../scala/shapeless3/deriving/kinds.scala | 144 +++++++++++++++--- 3 files changed, 133 insertions(+), 28 deletions(-) diff --git a/modules/deriving/src/main/scala/shapeless3/deriving/deriving.scala b/modules/deriving/src/main/scala/shapeless3/deriving/deriving.scala index d733baa..02c79d6 100644 --- a/modules/deriving/src/main/scala/shapeless3/deriving/deriving.scala +++ b/modules/deriving/src/main/scala/shapeless3/deriving/deriving.scala @@ -23,7 +23,7 @@ import scala.reflect.ClassTag type Id[t] = t type Const[c] = [t] =>> c -type ~>[A[_], B[_]] = [t] => A[t] => B[t] +infix type ~>[A[_], B[_]] = [t] => A[t] => B[t] /** Corresponds to `Applicative.pure` in Cats. */ type Pure[F[_]] = [a] => a => F[a] 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 9fbf071..95c37e8 100644 --- a/modules/deriving/src/main/scala/shapeless3/deriving/internals/kinds.scala +++ b/modules/deriving/src/main/scala/shapeless3/deriving/internals/kinds.scala @@ -12,26 +12,27 @@ object Kinds: type Tail[T] <: Tuple = T match case _ *: t => t - transparent inline def summonFirst[T]: Any = + /** For a tuple type `T`, summons the first given element type. */ + transparent inline def summonFirst[T <: Tuple]: Any = inline erasedValue[T] match case _: (a *: b) => - summonFrom { + summonFrom: case instance: a => instance case _ => summonFirst[b] - } - transparent inline def summonOnly[T]: Any = + /** For a tuple type `T`, summons exactly one given element type. Otherwise fails to compile. */ + transparent inline def summonOnly[T <: Tuple]: Any = inline erasedValue[T] match case _: (a *: b) => - summonFrom { + summonFrom: case instance: a => summonNone[b] instance case _ => summonOnly[b] - } - transparent inline def summonNone[T]: Unit = + /** For a tuple type `T`, proves that none of its element types are given in this scope. */ + transparent inline def summonNone[T <: Tuple]: Unit = inline erasedValue[T] match case _: EmptyTuple => () 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 aa5dc2d..d5e0a33 100644 --- a/modules/deriving/src/main/scala/shapeless3/deriving/kinds.scala +++ b/modules/deriving/src/main/scala/shapeless3/deriving/kinds.scala @@ -23,72 +23,142 @@ import scala.compiletime.* import scala.compiletime.ops.int.S import scala.deriving.* +/** + * A helper trait for specifying kinds supported by Shapeless. + * + * @see + * [[K0]], [[K1]], [[K11]], [[K2]] for examples how to use this trait. + * + * @tparam Up + * The upper bound of this kind. Use a type lambda to specify higher-kinds. + * @tparam Tup + * The upper bound of tuples with this kind. Should have the same kind as `Up` but result in a `Tuple`. + * @tparam Mono + * A type lambda that monomorphizes a type with kind `Up` - it applies it to the upper bounds of its type parameters. + * @tparam Head + * A type lambda that returns the head type of a tuple with kind `Tup`. + * @tparam Tail + * A type lambda that returns the tail type of a tuple with kind `Tup`. + * + * @define productToRepr + * Convert a product value to its equivalent representation as a typed tuple. + * + * @define coproductToRepr + * Convert a sum value to its equivalent representation as a union type. Noop at runtime. + * + * @define productFromRepr + * Construct a product value from its equivalent representation of a typed tuple. + * + * @define coproductFromRepr + * Construct a sum value from its equivalent representation of a union type. Noop at runtime. + */ trait Kind[Up <: AnyKind, Tup <: AnyKind, Mono[_ <: Up], Head[_ <: Tup] <: Up, Tail[_ <: Tup] <: Up]: self => - type of[M <: Mirror, O <: Up] = M { + /** Similar to [[Mirror.Of]] but generalized to this kind. */ + infix type of[M <: Mirror, O <: Up] = M { type MirroredType = O type MirroredMonoType = Mono[O] type MirroredElemTypes <: Tup } + /** A [[Mirror]] for types of this kind, including the given scope of the enclosing object. */ type Kind[M <: Mirror, O <: Up] = (M of O) { type Kind = self.type } + + /** A [[Mirror]] for types of this kind. */ type Generic[O <: Up] = Kind[Mirror, O] + + /** A [[Mirror.Product]] for types of this kind. */ type ProductGeneric[O <: Up] = Kind[Mirror.Product, O] + + /** A [[Mirror.Sum]] for types of this kind. */ type CoproductGeneric[O <: Up] = Kind[Mirror.Sum, O] object Generic: + + /** + * Attaches the given scope of the enclosing object to a given [[Mirror]] as a type refinement. + * + * The Scala compiler can automatically add type refinements to synthesized mirrors, but not to given mirrors in the + * current scope or to user-defined mirrors. The scope of the enclosing object is necessary to resolve extension + * methods defined on mirrors by Shapeless without an import. + */ given fromMirror[M <: Mirror, O <: Up](using m: M of O): Kind[m.type, O] = m.asInstanceOf + /** Summon or synthesize [[Generic]]. */ def Generic[O <: Up](using gen: Generic[O]): gen.type = gen + + /** Summon or synthesize [[ProductGeneric]]. */ def ProductGeneric[O <: Up](using gen: ProductGeneric[O]): gen.type = gen + + /** Summon or synthesize [[CoproductGeneric]]. */ def CoproductGeneric[O <: Up](using gen: CoproductGeneric[O]): gen.type = gen + /** Resolved instances of the type class `F` for all fields or variants of the type `T`. */ type Instances[F[_ <: Up], T <: Up] = ErasedInstances[self.type, F[T]] + + /** Resolved instances of the type class `F` for all fields of the product type `T`. */ type ProductInstances[F[_ <: Up], T <: Up] = ErasedProductInstances[self.type, F[T]] + + /** Resolved instances of the type class `F` for all variants of the sum type `T`. */ type CoproductInstances[F[_ <: Up], T <: Up] = ErasedCoproductInstances[self.type, F[T]] + /** A curried version of [[Instances]] that can be used as a context bound. */ type InstancesOf[F[_ <: Up]] = [T <: Up] =>> Instances[F, T] + + /** A curried version of [[ProductInstances]] that can be used as a context bound. */ type ProductInstancesOf[F[_ <: Up]] = [T <: Up] =>> ProductInstances[F, T] + + /** A curried version of [[CoproductInstances]] that can be used as a context bound. */ type CoproductInstancesOf[F[_ <: Up]] = [T <: Up] =>> CoproductInstances[F, T] + /** Summon instances of the type class `F` for all fields or variants of the type `T`. */ def Instances[F[_ <: Up], T <: Up](using inst: Instances[F, T]): inst.type = inst + + /** Summon instances of the type class `F` for all fields of the product type `T`. */ def ProductInstances[F[_ <: Up], T <: Up](using inst: ProductInstances[F, T]): inst.type = inst + + /** Summon instances of the type class `F` for all variants of the sum type `T`. */ def CoproductInstances[F[_ <: Up], T <: Up](using inst: CoproductInstances[F, T]): inst.type = inst + /** Applies `F` to all elements of the tuple type `T`. Similar to [[Tuple.Map]] but generalized to this kind. */ type LiftP[F[_ <: Up], T <: Tup] <: Tuple = Mono[T] match case _ *: _ => F[Head[T]] *: LiftP[F, Tail[T]] case _ => EmptyTuple + /** Given a [[Mirror]], provides instances of the type class `F` for all fields or variants of `T`. */ 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] + /** Given a [[Mirror.Product]], provides instances of the type class `F` for all fields of `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) + /** Given a [[Mirror.Sum]], provides instances of the type class `F` for all variants of `T`. */ 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 + * Summon the first given instance of `F` from the tuple type `T`. Remaining elements of `T` may or may not have an * instance of `F`. */ 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`. + * Summon the only given instance of `F` from the tuple type `T`. Remaining elements of `T` are guaranteed to not have + * an instance of `F` in scope. */ 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`. */ + /** Ensure that no element of the tuple type `T` has an instance of `F`. */ inline def summonNone[F[_ <: Up], T <: Tup]: Unit = Kinds.summonNone[LiftP[F, T]] extension [F[_ <: Up], T <: Up](gen: Generic[T]) + /** Derive an instance of `F[T]` depending on whether `T` is a product or sum type. */ inline def derive( f: => (ProductGeneric[T] & gen.type) ?=> F[T], g: => (CoproductGeneric[T] & gen.type) ?=> F[T] @@ -97,32 +167,42 @@ trait Kind[Up <: AnyKind, Tup <: AnyKind, Mono[_ <: Up], Head[_ <: Tup] <: Up, T case c: CoproductGeneric[T] => g(using c.asInstanceOf) extension [T <: Up](gen: CoproductGeneric[T]) + /** Use the first given instance of `F` among the variants of the sum type `T` to produce a result. */ inline def withFirst[F[_ <: Up], R](f: [t <: T] => F[t] => R): R = f(summonFirst[F, gen.MirroredElemTypes].asInstanceOf) + + /** Use the only given instance of `F` among the variants of the sum type `T` to produce a result. */ 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]) + /** Transform the type class `F` in these instances to `G` by applying a polymorphic function. */ 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 + + /** Widen the type class `F` in these instances to a super type `G`. Noop at runtime. */ + inline def widen[G[t <: Up] >: F[t]]: Instances[G, T] = inst.asInstanceOf extension [F[_ <: Up], T <: Up](inst: ProductInstances[F, T]) + /** Transform the type class `F` in these product instances to `G` by applying a polymorphic function. */ 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 + + /** Widen the type class `F` in these product instances to a super type `G`. Noop at runtime. */ + inline def widen[G[t <: Up] >: F[t]]: ProductInstances[G, T] = inst.asInstanceOf extension [F[_ <: Up], T <: Up](inst: CoproductInstances[F, T]) + /** Transform the type class `F` in these coproduct instances to `G` by applying a polymorphic function. */ 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 + + /** Widen the type class `F` in these coproduct instances to a super type `G`. Noop at runtime. */ + 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 + /** Returns the index of element type `E` in the tuple type `T` as a literal type, `-1` if `E` is not in `T`. */ + type IndexOf[E, T] = IndexOf0[E, T, 0] + type IndexOf0[E, T, I <: Int] <: Int = T match case EmptyTuple => -1 case x *: xs => x match @@ -130,16 +210,22 @@ object K0 extends Kind[Any, Tuple, Id, Kinds.Head, Kinds.Tail]: case _ => IndexOf0[E, xs, S[I]] @deprecated("Use summonFirst instead", "3.2.0") - transparent inline def summonFirst0[T]: Any = Kinds.summonFirst[T] + transparent inline def summonFirst0[T <: Tuple]: Any = Kinds.summonFirst[T] extension [T](gen: ProductGeneric[T]) + /** $productToRepr */ inline def toRepr(o: T): gen.MirroredElemTypes = Tuple.fromProduct(o.asInstanceOf).asInstanceOf[gen.MirroredElemTypes] + + /** $productFromRepr */ inline def fromRepr(r: gen.MirroredElemTypes): T = - gen.fromProduct(r.asInstanceOf) + gen.fromProduct(r) extension [T](gen: CoproductGeneric[T]) + /** $coproductToRepr */ inline def toRepr(o: T): Union[gen.MirroredElemTypes] = o.asInstanceOf + + /** $coproductFromRepr */ inline def fromRepr(r: Union[gen.MirroredElemTypes]): T = r.asInstanceOf extension [F[_], T](inst: Instances[F, T]) @@ -193,16 +279,22 @@ object K1 ]: @deprecated("Use summonFirst instead", "3.2.0") - transparent inline def summonFirst0[T]: Any = Kinds.summonFirst[T] + transparent inline def summonFirst0[T <: Tuple]: Any = Kinds.summonFirst[T] extension [T[_], A](gen: ProductGeneric[T]) + /** $productToRepr */ inline def toRepr(o: T[A]): gen.MirroredElemTypes[A] = Tuple.fromProduct(o.asInstanceOf).asInstanceOf[gen.MirroredElemTypes[A]] + + /** $productFromRepr */ inline def fromRepr(r: gen.MirroredElemTypes[A]): T[A] = - gen.fromProduct(r.asInstanceOf).asInstanceOf[T[A]] + gen.fromProduct(r).asInstanceOf[T[A]] extension [T[_], A](gen: CoproductGeneric[T]) + /** $coproductToRepr */ inline def toRepr(o: T[A]): Union[gen.MirroredElemTypes[A]] = o.asInstanceOf + + /** $coproductFromRepr */ inline def fromRepr(r: Union[gen.MirroredElemTypes[A]]): T[A] = r.asInstanceOf extension [F[_[_]], T[_]](inst: Instances[F, T]) @@ -260,13 +352,19 @@ object K11 type Const[c] = [f[_]] =>> c extension [T[_[_]], A[_]](gen: ProductGeneric[T]) + /** $productToRepr */ inline def toRepr(o: T[A]): gen.MirroredElemTypes[A] = Tuple.fromProduct(o.asInstanceOf).asInstanceOf[gen.MirroredElemTypes[A]] + + /** $productFromRepr */ inline def fromRepr(r: gen.MirroredElemTypes[A]): T[A] = - gen.fromProduct(r.asInstanceOf).asInstanceOf[T[A]] + gen.fromProduct(r).asInstanceOf[T[A]] extension [T[_[_]], A[_]](gen: CoproductGeneric[T]) + /** $coproductToRepr */ inline def toRepr(o: T[A]): Union[gen.MirroredElemTypes[A]] = o.asInstanceOf + + /** $coproductFromRepr */ inline def fromRepr(r: Union[gen.MirroredElemTypes[A]]): T[A] = r.asInstanceOf extension [F[_[_[_]]], T[_[_]]](inst: Instances[F, T]) @@ -329,16 +427,22 @@ object K2 type Const[c] = [t, u] =>> c @deprecated("Use summonFirst instead", "3.2.0") - transparent inline def summonFirst0[T]: Any = Kinds.summonFirst[T] + transparent inline def summonFirst0[T <: Tuple]: Any = Kinds.summonFirst[T] extension [T[_, _], A, B](gen: ProductGeneric[T]) + /** $productToRepr */ inline def toRepr(o: T[A, B]): gen.MirroredElemTypes[A, B] = Tuple.fromProduct(o.asInstanceOf).asInstanceOf[gen.MirroredElemTypes[A, B]] + + /** $productFromRepr */ inline def fromRepr(r: gen.MirroredElemTypes[A, B]): T[A, B] = - gen.fromProduct(r.asInstanceOf).asInstanceOf[T[A, B]] + gen.fromProduct(r).asInstanceOf[T[A, B]] extension [T[_, _], A, B](gen: CoproductGeneric[T]) + /** $coproductToRepr */ inline def toRepr(o: T[A, B]): Union[gen.MirroredElemTypes[A, B]] = o.asInstanceOf + + /** $coproductFromRepr */ inline def fromRepr(r: Union[gen.MirroredElemTypes[A, B]]): T[A, B] = r.asInstanceOf extension [F[_[_, _]], T[_, _]](inst: Instances[F, T]) From 59221b25cad8dc2daf8fd3b4d054293766dcf4d3 Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Wed, 21 Aug 2024 18:56:35 +0900 Subject: [PATCH 3/3] scala-native 0.5 (#235) --- .github/workflows/ci.yml | 2 +- build.sbt | 3 ++- project/plugins.sbt | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01fdf5a..930fadf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -217,7 +217,7 @@ jobs: - name: Submit Dependencies uses: scalacenter/sbt-dependency-submission@v2 with: - modules-ignore: rootjs_3 docs_3 rootjvm_3 rootnative_3 shapeless3-local_native0.4_3 shapeless3-local_sjs1_3 shapeless3-local_3 + modules-ignore: rootjs_3 docs_3 rootjvm_3 rootnative_3 shapeless3-local_native0.5_3 shapeless3-local_sjs1_3 shapeless3-local_3 configs-ignore: test scala-tool scala-doc-tool test-internal site: diff --git a/build.sbt b/build.sbt index 163d393..c2a2c33 100644 --- a/build.sbt +++ b/build.sbt @@ -19,6 +19,7 @@ val jsSettings = Def.settings( ) val nativeSettings = Def.settings( + mimaPreviousArtifacts := Set.empty, // TODO re-enable tlVersionIntroduced := Map("3" -> "3.1.0") ) @@ -64,7 +65,7 @@ lazy val deriving = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(commonSettings) .jsEnablePlugins(ScalaJSJUnitPlugin) .nativeEnablePlugins(ScalaNativeJUnitPlugin) - .settings(libraryDependencies += "org.typelevel" %%% "cats-core" % "2.11.0" % "test") + .settings(libraryDependencies += "org.typelevel" %%% "cats-core" % "2.12.0" % "test") .settings( mimaBinaryIssueFilters ++= Seq( // Those are objects: diff --git a/project/plugins.sbt b/project/plugins.sbt index 05f8a4b..a5d754b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,7 +2,7 @@ addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "0.7.2") addSbtPlugin("org.typelevel" % "sbt-typelevel-mergify" % "0.7.2") addSbtPlugin("org.typelevel" % "sbt-typelevel-site" % "0.7.2") addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0") -addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.17") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.4") addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2") addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.3.2") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")