diff --git a/core/src/main/scala-3/cats/derived/DerivedEq.scala b/core/src/main/scala-3/cats/derived/DerivedEq.scala index 9311254c..0a1d3ce0 100644 --- a/core/src/main/scala-3/cats/derived/DerivedEq.scala +++ b/core/src/main/scala-3/cats/derived/DerivedEq.scala @@ -13,6 +13,7 @@ Make sure that A satisfies one of the following conditions: type DerivedEq[A] = Derived[Eq[A]] object DerivedEq: type Or[A] = Derived.Or[Eq[A]] + inline def apply[A]: Eq[A] = import DerivedEq.given summonInline[DerivedEq[A]].instance @@ -42,5 +43,5 @@ object DerivedEq: [t] => (eqt: F[t], x: t, y: t) => eqt.eqv(x, y) object Strict: - given product[A](using inst: => K0.ProductInstances[Eq, A]): DerivedEq[A] = + given product[A](using => K0.ProductInstances[Eq, A]): DerivedEq[A] = new Product[Eq, A] {} diff --git a/core/src/main/scala-3/cats/derived/DerivedHash.scala b/core/src/main/scala-3/cats/derived/DerivedHash.scala index a1e9101a..1ee5bd32 100644 --- a/core/src/main/scala-3/cats/derived/DerivedHash.scala +++ b/core/src/main/scala-3/cats/derived/DerivedHash.scala @@ -14,10 +14,16 @@ Make sure that A satisfies one of the following conditions: type DerivedHash[A] = Derived[Hash[A]] object DerivedHash: type Or[A] = Derived.Or[Hash[A]] + inline def apply[A]: Hash[A] = import DerivedHash.given summonInline[DerivedHash[A]].instance + inline def strict[A]: Hash[A] = + import DerivedHash.given + import Strict.product + summonInline[DerivedHash[A]].instance + // These instances support singleton types unlike the instances in Cats' kernel. given boolean[A <: Boolean]: DerivedHash[A] = Hash.fromUniversalHashCode given byte[A <: Byte]: DerivedHash[A] = Hash.fromUniversalHashCode @@ -57,3 +63,7 @@ object DerivedHash: final override def hash(x: A): Int = inst.fold[Int](x)([t] => (h: F[t], x: t) => h.hash(x)) + + object Strict: + given product[A <: scala.Product](using => K0.ProductInstances[Hash, A]): DerivedHash[A] = + new Product[Hash, A] {} diff --git a/core/src/main/scala-3/cats/derived/package.scala b/core/src/main/scala-3/cats/derived/package.scala index cf908fc1..225413b0 100644 --- a/core/src/main/scala-3/cats/derived/package.scala +++ b/core/src/main/scala-3/cats/derived/package.scala @@ -59,9 +59,11 @@ object semiauto: object strict: extension (x: Eq.type) inline def derived[A]: Eq[A] = DerivedEq.strict[A] + extension (x: Hash.type) inline def derived[A]: Hash[A] = DerivedHash.strict[A] object semiauto: inline def eq[A]: Eq[A] = DerivedEq.strict[A] + inline def hash[A]: Hash[A] = DerivedHash.strict[A] object auto: object eq: diff --git a/core/src/test/scala-3/cats/derived/HashSuite.scala b/core/src/test/scala-3/cats/derived/HashSuite.scala index e54a1c17..fca96c53 100644 --- a/core/src/test/scala-3/cats/derived/HashSuite.scala +++ b/core/src/test/scala-3/cats/derived/HashSuite.scala @@ -30,6 +30,11 @@ class HashSuite extends KittensSuite: import semiInstances.given validate("semiauto.hash") + locally: + import strictInstances.given + validate("strict.semiauto.hash") + testNoInstance("strict.semiauto.hash", "Top") + locally: import derivedInstances.* val instance = "derived.hash" @@ -58,6 +63,18 @@ object HashSuite: given Hash[EnumK0] = semiauto.hash given Hash[Singletons[Int]] = semiauto.hash + object strictInstances: + given Hash[IList[Int]] = strict.semiauto.hash + given Hash[Inner] = strict.semiauto.hash + given Hash[Outer] = strict.semiauto.hash + given Hash[Interleaved[Int]] = strict.semiauto.hash + given Hash[Tree[Int]] = strict.semiauto.hash + given Hash[Recursive] = strict.semiauto.hash + given Hash[EnumK0] = strict.semiauto.hash + given Hash[Singletons[Int]] = + given [A <: Singleton: ValueOf]: Hash[A] = Hash.fromUniversalHashCode + strict.semiauto.hash + object derivedInstances: case class IList[A](x: ADTs.IList[A]) derives Hash case class Inner(x: ADTs.Inner) derives Hash