Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use context bounds to simplify signatures #632

Merged
merged 1 commit into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ val munitVersion = "1.0.0-M10"
val disciplineMunitVersion = "2.0.0-M3"
val kindProjectorVersion = "0.13.2"
val shapeless2Version = "2.3.10"
val shapeless3Version = "3.3.0"
val shapeless3Version = "3.4.0"

lazy val commonSettings = Seq(
scalacOptions ++= Seq(
Expand Down
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