Skip to content

Commit

Permalink
Use summonFrom to prioritize DerivedEmpty instances (#355)
Browse files Browse the repository at this point in the history
  • Loading branch information
bplommer authored Jun 2, 2021
1 parent 6b5154d commit 851c322
Showing 1 changed file with 13 additions and 8 deletions.
21 changes: 13 additions & 8 deletions core/src/main/scala-3/cats/derived/empty.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,34 @@ package cats.derived

import alleycats.Empty
import shapeless3.deriving.K0
import scala.compiletime.summonFrom

object empty extends EmptyDerivation

trait DerivedEmpty[A] extends Empty[A]:
protected def emptyValue(): A
lazy val empty: A = emptyValue()

object DerivedEmpty extends DerivedEmptyLowPriority:
given delegated[A](using A: => Empty[A]): DerivedEmpty[A] =
object DerivedEmpty:
inline given [A]: DerivedEmpty[A] = summonFrom {
case given Empty[A] => delegated
case given K0.Generic[A] => derived
}

def delegated[A](using A: => Empty[A]): DerivedEmpty[A] =
() => A.empty

inline def derived[A](using gen: K0.Generic[A]): DerivedEmpty[A] =
inline gen match
case given K0.ProductGeneric[A] => DerivedEmpty.product
case given K0.CoproductGeneric[A] => DerivedEmpty.coproduct

def product[A](using inst: K0.ProductInstances[DerivedEmpty, A]): DerivedEmpty[A] =
() => inst.construct([A] => (A: DerivedEmpty[A]) => A.empty)

inline def coproduct[A](using gen: K0.CoproductGeneric[A]): DerivedEmpty[A] =
K0.summonFirst[DerivedEmpty, gen.MirroredElemTypes, A]

private[derived] sealed abstract class DerivedEmptyLowPriority:
inline given derived[A](using gen: K0.Generic[A]): DerivedEmpty[A] =
inline gen match
case given K0.ProductGeneric[A] => DerivedEmpty.product
case given K0.CoproductGeneric[A] => DerivedEmpty.coproduct

trait EmptyDerivation:
extension (E: Empty.type)
def derived[A](using instance: DerivedEmpty[A]): Empty[A] = instance

0 comments on commit 851c322

Please sign in to comment.