Skip to content

Commit

Permalink
Deep and Coproduct Empty derivation (#349)
Browse files Browse the repository at this point in the history
  • Loading branch information
joroKr21 authored Jun 1, 2021
1 parent a033a34 commit 6b5154d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
26 changes: 20 additions & 6 deletions core/src/main/scala-3/cats/derived/empty.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,26 @@ import shapeless3.deriving.K0

object empty extends EmptyDerivation

class ProductEmpty[F[x] <: Empty[x], A](
using inst: K0.ProductInstances[F, A]
) extends Empty[A]:
val empty: A = inst.construct([A] => (F: F[A]) => F.empty)
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] =
() => A.empty

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)
inline def derived[A](using gen: K0.ProductGeneric[A]): Empty[A] =
ProductEmpty(using K0.mkProductInstances)
def derived[A](using instance: DerivedEmpty[A]): Empty[A] = instance
11 changes: 11 additions & 0 deletions core/src/test/scala-3/cats/derived/EmptyTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package cats.derived

import alleycats._
import cats._
import cats.derived.all._

class EmptyTests:
case class Foo(i: Int, b: IntTree) derives Empty
enum IntTree:
case Leaf
case Node(left: IntTree, value: Int, right: IntTree)

0 comments on commit 6b5154d

Please sign in to comment.