Skip to content

Commit

Permalink
Use context bounds to simplify signatures (#632)
Browse files Browse the repository at this point in the history
Updates shapeless to 3.4.0
  • Loading branch information
joroKr21 authored Jan 11, 2024
1 parent 5da32de commit ea2e7c1
Show file tree
Hide file tree
Showing 27 changed files with 219 additions and 200 deletions.
8 changes: 4 additions & 4 deletions core/src/main/scala-3/cats/derived/DerivedAlternative.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cats.derived

import cats.Alternative
import shapeless3.deriving.K1
import shapeless3.deriving.K1.*

import scala.annotation.*
import scala.compiletime.*
Expand Down Expand Up @@ -31,14 +31,14 @@ object DerivedAlternative:
new Derived.Lazy(() => F.unify.compose(using G.unify)) with Alternative[[x] =>> F[G[x]]]:
export delegate.*

given product[F[_]](using inst: => K1.ProductInstances[Or, F]): DerivedAlternative[F] =
given product[F[_]](using inst: => ProductInstances[Or, F]): DerivedAlternative[F] =
Strict.product(using inst.unify)

trait Product[T[f[_]] <: Alternative[f], F[_]](using K1.ProductInstances[T, F])
trait Product[T[f[_]] <: Alternative[f], F[_]: ProductInstancesOf[T]]
extends Alternative[F],
DerivedNonEmptyAlternative.Product[T, F],
DerivedMonoidK.Product[T, F]

object Strict:
given product[F[_]](using K1.ProductInstances[Alternative, F]): DerivedAlternative[F] =
given product[F[_]: ProductInstancesOf[Alternative]]: DerivedAlternative[F] =
new Alternative[F] with Product[Alternative, F] {}
9 changes: 5 additions & 4 deletions core/src/main/scala-3/cats/derived/DerivedApplicative.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package cats.derived

import cats.{Applicative, Monoid}
import shapeless3.deriving.{Const, K1}
import shapeless3.deriving.Const
import shapeless3.deriving.K1.*

import scala.annotation.*
import scala.compiletime.*
Expand Down Expand Up @@ -33,19 +34,19 @@ object DerivedApplicative:
new Derived.Lazy(() => F.unify.compose(using G.unify)) with Applicative[[x] =>> F[G[x]]]:
export delegate.*

given [F[_]](using inst: => K1.ProductInstances[Or, F]): DerivedApplicative[F] =
given [F[_]](using inst: => ProductInstances[Or, F]): DerivedApplicative[F] =
Strict.product(using inst.unify)

@deprecated("Kept for binary compatibility", "3.2.0")
protected given [F[_]: Or, G[_]: Or]: DerivedApplicative[[x] =>> F[G[x]]] = nested

trait Product[T[f[_]] <: Applicative[f], F[_]](using inst: K1.ProductInstances[T, F])
trait Product[T[f[_]] <: Applicative[f], F[_]](using inst: ProductInstances[T, F])
extends Applicative[F],
DerivedApply.Product[T, F]:

final override def pure[A](x: A): F[A] =
inst.construct([f[_]] => (F: T[f]) => F.pure[A](x))

object Strict:
given product[F[_]](using K1.ProductInstances[Applicative, F]): DerivedApplicative[F] =
given product[F[_]: ProductInstancesOf[Applicative]]: DerivedApplicative[F] =
new Applicative[F] with Product[Applicative, F] {}
9 changes: 5 additions & 4 deletions core/src/main/scala-3/cats/derived/DerivedApply.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package cats.derived

import cats.{Apply, Semigroup}
import shapeless3.deriving.{Const, K1}
import shapeless3.deriving.Const
import shapeless3.deriving.K1.*

import scala.annotation.*
import scala.compiletime.*
Expand Down Expand Up @@ -33,18 +34,18 @@ object DerivedApply:
new Derived.Lazy(() => F.unify.compose(using G.unify)) with Apply[[x] =>> F[G[x]]]:
export delegate.*

given [F[_]](using inst: => K1.ProductInstances[Or, F]): DerivedApply[F] =
given [F[_]](using inst: => ProductInstances[Or, F]): DerivedApply[F] =
Strict.product(using inst.unify)

@deprecated("Kept for binary compatibility", "3.2.0")
protected given [F[_]: Or, G[_]: Or]: DerivedApply[[x] =>> F[G[x]]] = nested

trait Product[T[f[_]] <: Apply[f], F[_]](using inst: K1.ProductInstances[T, F]) extends Apply[F]:
trait Product[T[f[_]] <: Apply[f], F[_]](using inst: ProductInstances[T, F]) extends Apply[F]:
private lazy val F = new DerivedFunctor.Generic[T, F] {}
final override def map[A, B](fa: F[A])(f: A => B): F[B] = F.map(fa)(f)
final override def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] =
inst.map2(ff, fa)([f[_]] => (F: T[f], ff: f[A => B], fa: f[A]) => F.ap(ff)(fa))

object Strict:
given product[F[_]](using K1.ProductInstances[Apply, F]): DerivedApply[F] =
given product[F[_]: ProductInstancesOf[Apply]]: DerivedApply[F] =
new Product[Apply, F] {}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cats.derived

import cats.kernel.CommutativeMonoid
import shapeless3.deriving.K0
import shapeless3.deriving.K0.*

import scala.annotation.*
import scala.compiletime.*
Expand All @@ -22,13 +22,13 @@ object DerivedCommutativeMonoid:
import Strict.given
summonInline[DerivedCommutativeMonoid[A]].instance

given [A](using inst: => K0.ProductInstances[Or, A]): DerivedCommutativeMonoid[A] =
given [A](using inst: => ProductInstances[Or, A]): DerivedCommutativeMonoid[A] =
Strict.product(using inst.unify)

trait Product[F[x] <: CommutativeMonoid[x], A](using @unused inst: K0.ProductInstances[F, A])
trait Product[F[x] <: CommutativeMonoid[x], A](using @unused inst: ProductInstances[F, A])
extends DerivedMonoid.Product[F, A],
CommutativeMonoid[A]

object Strict:
given product[A](using K0.ProductInstances[CommutativeMonoid, A]): DerivedCommutativeMonoid[A] =
given product[A: ProductInstancesOf[CommutativeMonoid]]: DerivedCommutativeMonoid[A] =
new Product[CommutativeMonoid, A] {}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cats.derived

import cats.kernel.CommutativeSemigroup
import shapeless3.deriving.K0
import shapeless3.deriving.K0.*

import scala.annotation.*
import scala.compiletime.*
Expand All @@ -22,13 +22,13 @@ object DerivedCommutativeSemigroup:
import Strict.given
summonInline[DerivedCommutativeSemigroup[A]].instance

given [A](using inst: => K0.ProductInstances[Or, A]): DerivedCommutativeSemigroup[A] =
given [A](using inst: => ProductInstances[Or, A]): DerivedCommutativeSemigroup[A] =
Strict.product(using inst.unify)

trait Product[F[x] <: CommutativeSemigroup[x], A](using @unused inst: K0.ProductInstances[F, A])
trait Product[F[x] <: CommutativeSemigroup[x], A](using @unused inst: ProductInstances[F, A])
extends DerivedSemigroup.Product[F, A],
CommutativeSemigroup[A]

object Strict:
given product[A](using K0.ProductInstances[CommutativeSemigroup, A]): DerivedCommutativeSemigroup[A] =
given product[A: ProductInstancesOf[CommutativeSemigroup]]: DerivedCommutativeSemigroup[A] =
new Product[CommutativeSemigroup, A] {}
13 changes: 7 additions & 6 deletions core/src/main/scala-3/cats/derived/DerivedContravariant.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package cats.derived

import cats.Contravariant
import shapeless3.deriving.{Const, K1}
import shapeless3.deriving.Const
import shapeless3.deriving.K1.*

import scala.annotation.*
import scala.compiletime.*
Expand Down Expand Up @@ -33,20 +34,20 @@ object DerivedContravariant:
new Derived.Lazy(() => F.unify.composeContravariant(using G.unify)) with Contravariant[[x] =>> F[G[x]]]:
export delegate.*

given [F[_]](using inst: => K1.Instances[Or, F]): DerivedContravariant[F] =
given [F[_]](using inst: => Instances[Or, F]): DerivedContravariant[F] =
generic(using inst.unify)

@deprecated("Kept for binary compatibility", "3.2.0")
protected given [F[_]: DerivedFunctor.Or, G[_]: Or]: DerivedContravariant[[x] =>> F[G[x]]] = nested

private def generic[F[_]](using K1.Instances[Contravariant, F]): DerivedContravariant[F] =
private def generic[F[_]: InstancesOf[Contravariant]]: DerivedContravariant[F] =
new Generic[Contravariant, F] {}

trait Generic[T[f[_]] <: Contravariant[f], F[_]](using inst: K1.Instances[T, F]) extends Contravariant[F]:
trait Generic[T[f[_]] <: Contravariant[f], F[_]](using inst: Instances[T, F]) extends Contravariant[F]:
final override def contramap[A, B](fa: F[A])(f: B => A): F[B] =
inst.map(fa)([f[_]] => (T: T[f], fa: f[A]) => T.contramap(fa)(f))

object Strict:
given product[F[_]](using K1.ProductInstances[Contravariant, F]): DerivedContravariant[F] = generic
given coproduct[F[_]](using inst: => K1.CoproductInstances[Or, F]): DerivedContravariant[F] =
given product[F[_]: ProductInstancesOf[Contravariant]]: DerivedContravariant[F] = generic
given coproduct[F[_]](using inst: => CoproductInstances[Or, F]): DerivedContravariant[F] =
generic(using inst.unify)
14 changes: 7 additions & 7 deletions core/src/main/scala-3/cats/derived/DerivedEmpty.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cats.derived

import alleycats.Empty
import shapeless3.deriving.K0
import shapeless3.deriving.K0.*

import scala.annotation.*
import scala.compiletime.*
Expand All @@ -24,12 +24,12 @@ object DerivedEmpty:
import Strict.given
summonInline[DerivedEmpty[A]].instance

given product[A](using inst: K0.ProductInstances[Or, A]): DerivedEmpty[A] = Strict.product(using inst.unify)
inline given coproduct[A](using gen: K0.CoproductGeneric[A]): DerivedEmpty[A] = Strict.coproduct
given product[A: ProductInstancesOf[Or]]: DerivedEmpty[A] = Strict.product(using ProductInstances.unify)
inline given coproduct[A: CoproductGeneric]: DerivedEmpty[A] = Strict.coproduct

object Strict:
given product[A](using inst: K0.ProductInstances[Empty, A]): DerivedEmpty[A] =
Empty(inst.construct([a] => (A: Empty[a]) => A.empty))
given product[A: ProductInstancesOf[Empty]]: DerivedEmpty[A] =
Empty(ProductInstances.construct([a] => (A: Empty[a]) => A.empty))

inline given coproduct[A](using gen: K0.CoproductGeneric[A]): DerivedEmpty[A] =
Empty(gen.withOnly[Or, A]([a <: A] => (A: Or[a]) => A.unify.empty))
inline given coproduct[A: CoproductGeneric]: DerivedEmpty[A] =
Empty(CoproductGeneric.withOnly[Or, A]([a <: A] => (A: Or[a]) => A.unify.empty))
15 changes: 8 additions & 7 deletions core/src/main/scala-3/cats/derived/DerivedEmptyK.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package cats.derived

import alleycats.{Empty, EmptyK}
import shapeless3.deriving.{Const, K1}
import shapeless3.deriving.Const
import shapeless3.deriving.K1.*

import scala.annotation.*
import scala.compiletime.summonInline
Expand Down Expand Up @@ -44,8 +45,8 @@ object DerivedEmptyK:
lazy val g = G.unify
def empty[A]: F[G[A]] = f.pure(g.empty)

given product[F[_]](using inst: K1.ProductInstances[Or, F]): DerivedEmptyK[F] = Strict.product(using inst.unify)
inline given coproduct[F[_]](using K1.CoproductGeneric[F]): DerivedEmptyK[F] = Strict.coproduct
given product[F[_]: ProductInstancesOf[Or]]: DerivedEmptyK[F] = Strict.product(using ProductInstances.unify)
inline given coproduct[F[_]: CoproductGeneric]: DerivedEmptyK[F] = Strict.coproduct

@deprecated("Kept for binary compatibility", "3.2.0")
protected given [F[_], G[_]](using F: Or[F]): DerivedEmptyK[[x] =>> F[G[x]]] =
Expand All @@ -58,8 +59,8 @@ object DerivedEmptyK:
nested(using ev)

object Strict:
given product[F[_]](using inst: K1.ProductInstances[EmptyK, F]): DerivedEmptyK[F] = new EmptyK[F]:
def empty[A]: F[A] = inst.construct([f[_]] => (F: EmptyK[f]) => F.empty[A])
given product[F[_]: ProductInstancesOf[EmptyK]]: DerivedEmptyK[F] = new EmptyK[F]:
def empty[A]: F[A] = ProductInstances.construct([f[_]] => (F: EmptyK[f]) => F.empty[A])

inline given coproduct[F[_]](using gen: K1.CoproductGeneric[F]): DerivedEmptyK[F] =
gen.withOnly[Or, EmptyK[F]]([f[x] <: F[x]] => (F: Or[f]) => F.unify.asInstanceOf[EmptyK[F]])
inline given coproduct[F[_]: CoproductGeneric]: DerivedEmptyK[F] =
CoproductGeneric.withOnly[Or, EmptyK[F]]([f[x] <: F[x]] => (F: Or[f]) => F.unify.asInstanceOf[EmptyK[F]])
15 changes: 8 additions & 7 deletions core/src/main/scala-3/cats/derived/DerivedEq.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package cats.derived

import cats.Eq
import shapeless3.deriving.{Complete, K0}
import shapeless3.deriving.Complete
import shapeless3.deriving.K0.*

import scala.annotation.*
import scala.compiletime.*
Expand All @@ -27,22 +28,22 @@ object DerivedEq:
given singleton[A <: Singleton: ValueOf]: DerivedEq[A] =
Eq.allEqual

given product[A](using inst: => K0.ProductInstances[Or, A]): DerivedEq[A] =
given product[A](using inst: => ProductInstances[Or, A]): DerivedEq[A] =
Strict.product(using inst.unify)

given coproduct[A](using inst: => K0.CoproductInstances[Or, A]): DerivedEq[A] =
given K0.CoproductInstances[Eq, A] = inst.unify
given coproduct[A](using inst: => CoproductInstances[Or, A]): DerivedEq[A] =
given CoproductInstances[Eq, A] = inst.unify
new Coproduct[Eq, A] {}

trait Product[F[x] <: Eq[x], A](using inst: K0.ProductInstances[F, A]) extends Eq[A]:
trait Product[F[x] <: Eq[x], A](using inst: ProductInstances[F, A]) extends Eq[A]:
final override def eqv(x: A, y: A): Boolean = inst.foldLeft2(x, y)(true: Boolean):
[t] => (acc: Boolean, eqt: F[t], x: t, y: t) => Complete(!eqt.eqv(x, y))(false)(true)

trait Coproduct[F[x] <: Eq[x], A](using inst: K0.CoproductInstances[F, A]) extends Eq[A]:
trait Coproduct[F[x] <: Eq[x], A](using inst: CoproductInstances[F, A]) extends Eq[A]:
final override def eqv(x: A, y: A): Boolean = inst.fold2(x, y)(false):
[t] => (eqt: F[t], x: t, y: t) => eqt.eqv(x, y)

object Strict:
export DerivedEq.coproduct
given product[A](using K0.ProductInstances[Eq, A]): DerivedEq[A] =
given product[A: ProductInstancesOf[Eq]]: DerivedEq[A] =
new Product[Eq, A] {}
20 changes: 12 additions & 8 deletions core/src/main/scala-3/cats/derived/DerivedFoldable.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package cats.derived

import cats.{Eval, Foldable}
import shapeless3.deriving.{Const, Continue, K1}
import shapeless3.deriving.{Const, Continue}
import shapeless3.deriving.K1.*

import scala.annotation.*
import scala.compiletime.*
Expand Down Expand Up @@ -34,31 +35,34 @@ object DerivedFoldable:
new Derived.Lazy(() => F.unify.compose(using G.unify)) with Foldable[[x] =>> F[G[x]]]:
export delegate.*

given [F[_]](using inst: K1.ProductInstances[Or, F]): DerivedFoldable[F] = Strict.product(using inst.unify)
given [F[_]](using => K1.CoproductInstances[Or, F]): DerivedFoldable[F] = Strict.coproduct
given [F[_]: ProductInstancesOf[Or]]: DerivedFoldable[F] =
Strict.product(using ProductInstances.unify)

given [F[_]](using => CoproductInstances[Or, F]): DerivedFoldable[F] =
Strict.coproduct

@deprecated("Kept for binary compatibility", "3.2.0")
protected given [F[_]: Or, G[_]: Or]: DerivedFoldable[[x] =>> F[G[x]]] = nested

trait Product[T[f[_]] <: Foldable[f], F[_]](using inst: K1.ProductInstances[T, F]) extends Foldable[F]:
trait Product[T[f[_]] <: Foldable[f], F[_]](using inst: ProductInstances[T, F]) extends Foldable[F]:
final override def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B =
inst.foldLeft(fa)(b)([f[_]] => (b: B, F: T[f], fa: f[A]) => Continue(F.foldLeft(fa, b)(f)))

final override def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
inst.foldRight(fa)(lb):
[f[_]] => (F: T[f], fa: f[A], lb: Eval[B]) => Continue(Eval.defer(F.foldRight(fa, lb)(f)))

trait Coproduct[T[f[_]] <: Foldable[f], F[_]](using inst: K1.CoproductInstances[T, F]) extends Foldable[F]:
trait Coproduct[T[f[_]] <: Foldable[f], F[_]](using inst: CoproductInstances[T, F]) extends Foldable[F]:
final override def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B =
inst.fold(fa)([f[_]] => (F: T[f], fa: f[A]) => F.foldLeft(fa, b)(f))

final override def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
inst.fold(fa)([f[_]] => (F: T[f], fa: f[A]) => Eval.defer(F.foldRight(fa, lb)(f)))

object Strict:
given product[F[_]](using K1.ProductInstances[Foldable, F]): DerivedFoldable[F] =
given product[F[_]: ProductInstancesOf[Foldable]]: DerivedFoldable[F] =
new Product[Foldable, F] {}

given coproduct[F[_]](using inst: => K1.CoproductInstances[Or, F]): DerivedFoldable[F] =
given K1.CoproductInstances[Foldable, F] = inst.unify
given coproduct[F[_]](using inst: => CoproductInstances[Or, F]): DerivedFoldable[F] =
given CoproductInstances[Foldable, F] = inst.unify
new Coproduct[Foldable, F] {}
14 changes: 8 additions & 6 deletions core/src/main/scala-3/cats/derived/DerivedFunctor.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package cats.derived

import cats.Functor
import shapeless3.deriving.{Const, K1}
import shapeless3.deriving.Const
import shapeless3.deriving.K1.*

import scala.annotation.*
import scala.compiletime.*
Expand Down Expand Up @@ -40,7 +41,7 @@ object DerivedFunctor:
): DerivedFunctor[[x] =>> F[G[x]]] =
F.unify.compose(using G.unify)

given [F[_]](using inst: => K1.Instances[Or, F]): DerivedFunctor[F] =
given [F[_]](using inst: => Instances[Or, F]): DerivedFunctor[F] =
generic(using inst.unify)

@deprecated("Kept for binary compatibility", "3.2.0")
Expand All @@ -54,13 +55,14 @@ object DerivedFunctor:
): DerivedFunctor[[x] =>> F[G[x]]] =
nested(using F, G)

private def generic[F[_]](using K1.Instances[Functor, F]): DerivedFunctor[F] =
private def generic[F[_]: InstancesOf[Functor]]: DerivedFunctor[F] =
new Generic[Functor, F] {}

trait Generic[T[f[_]] <: Functor[f], F[_]](using inst: K1.Instances[T, F]) extends Functor[F]:
trait Generic[T[f[_]] <: Functor[f], F[_]](using inst: Instances[T, F]) extends Functor[F]:
final override def map[A, B](fa: F[A])(f: A => B): F[B] =
inst.map(fa)([f[_]] => (F: T[f], fa: f[A]) => F.map(fa)(f))

object Strict:
given product[F[_]](using K1.ProductInstances[Functor, F]): DerivedFunctor[F] = generic
given coproduct[F[_]](using inst: => K1.CoproductInstances[Or, F]): DerivedFunctor[F] = generic(using inst.unify)
given product[F[_]: ProductInstancesOf[Functor]]: DerivedFunctor[F] = generic
given coproduct[F[_]](using inst: => CoproductInstances[Or, F]): DerivedFunctor[F] =
generic(using inst.unify)
Loading

0 comments on commit ea2e7c1

Please sign in to comment.