dev.constructive.eo.generics
Auto-derivation entry points for EO optics — Scala 3 quoted macros for Lens / Prism / Plated. Scaffolds on Mateusz Kubuszok's hearth macro-commons library.
Derived setters call the primary constructor directly (new S(...), never .copy) — uniform across case classes and enum cases, but the emitted call carries no outer accessor, so derive only for '''top-level''' ADTs, not types nested inside a class.
Attributes
Members list
Grouped members
Constructors
Derive a lens from one or more case-class field accessors. Two-step partial application — lens[Person](_.age) — pins S while letting the focus type be inferred. Works on any N-field case class or Scala 3 enum case (emits new S(…), doesn't require .copy).
Derive a lens from one or more case-class field accessors. Two-step partial application — lens[Person](_.age) — pins S while letting the focus type be inferred. Works on any N-field case class or Scala 3 enum case (emits new S(…), doesn't require .copy).
The return type is arity-and-cover driven:
- partial cover, one selector →
SimpleLens[S, A, XA]withXAthe NamedTuple complement of the non-focused fields; - partial cover, N ≥ 2 selectors →
SimpleLenswith NamedTuple focus in '''selector''' order and NamedTuple complement in '''declaration''' order among non-focused fields; - full cover at any arity (including
lens[Wrapper](_.value)on a 1-field case class) →BijectionIso[S, S, NT, NT].
Selectors must be single-field accessors — nested paths (_.a.b), duplicates, and unknown fields are compile errors.
Attributes
- Example
-
case class Person(name: String, age: Int) val ageLens = lens[Person](_.age) val asTuple = lens[Person](_.name, _.age) // full cover → BijectionIso - Source
- package.scala
Derive a dev.constructive.eo.optics.Plated for a recursive ADT — the immediate same-typed-children self-traversal that powers transform / rewrite / children / universe. Focuses every field whose type is exactly S across all cases; works on enums, sealed hierarchies, and recursive case classes.
Derive a dev.constructive.eo.optics.Plated for a recursive ADT — the immediate same-typed-children self-traversal that powers transform / rewrite / children / universe. Focuses every field whose type is exactly S across all cases; works on enums, sealed hierarchies, and recursive case classes.
Attributes
- Example
-
enum Expr: case Var(name: String) case App(f: Expr, x: Expr) case Lam(bind: String, body: Expr) given Plated[Expr] = plate[Expr] Plated.transform { case Expr.Var(n) => Expr.Var(n.toUpperCase); case e => e }(tree) - Source
- package.scala
Derive a Prism focusing on one variant of a sum type. Works on Scala 3 enums, sealed traits, and union types via Hearth's Enum.parse[S]. A must be a '''direct child''' of S — anything else is a compile error listing the known children.
Derive a Prism focusing on one variant of a sum type. Works on Scala 3 enums, sealed traits, and union types via Hearth's Enum.parse[S]. A must be a '''direct child''' of S — anything else is a compile error listing the known children.
Attributes
- Example
-
enum Shape: case Circle(r: Double) case Square(s: Double) val circleP = prism[Shape, Shape.Circle] val intP = prism[Int | String, Int] - Source
- package.scala
Type members
Classlikes
Compile-time derivation of a Lens (or Iso on full coverage) from one or more case-class accessors.
Compile-time derivation of a Lens (or Iso on full coverage) from one or more case-class accessors.
case class Person(age: Int, name: String)
val ageL = lens[Person](_.age) // SimpleLens, complement = remaining fields NT
val asTuple = lens[Person](_.name, _.age) // BijectionIso (full cover)
- Single-selector, partial cover →
SimpleLens[S, A, XA]withXAthe structural complement (givestransform/place/transferfor free). - Multi-selector, partial cover →
SimpleLenswith NamedTuple focus (SELECTOR order) and NamedTuple complement (DECLARATION order among non-focused fields). - Full cover at any arity →
BijectionIso[S, S, NT, NT].
Constructor synthesis routes through Hearth's CaseClass.parse[S] + construct[Id], so parameterised / recursive types and Scala 3 enum cases (which lack .copy) work uniformly via new S(...).
Attributes
- Source
- LensMacro.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
LensMacro.type
Quote-context selector-AST helpers shared between LensMacro and the JsonPrismMacro / AvroPrismMacro cursor macros. All parse single-field selector lambdas (_.fieldName) and validate non-duplicates; the per-macro divergence is just the error-message tag.
Quote-context selector-AST helpers shared between LensMacro and the JsonPrismMacro / AvroPrismMacro cursor macros. All parse single-field selector lambdas (_.fieldName) and validate non-duplicates; the per-macro divergence is just the error-message tag.
Attributes
- Source
- MacroSelectors.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
MacroSelectors.type
Partially-applied witness produced by lens.
Partially-applied witness produced by lens.
Attributes
- Source
- package.scala
- Supertypes
-
class Objecttrait Matchableclass Any
Compile-time derivation of a dev.constructive.eo.optics.Plated for a recursive ADT S.
Compile-time derivation of a dev.constructive.eo.optics.Plated for a recursive ADT S.
The derived plate focuses the immediate same-typed children of every case: each field whose declared type is exactly S (the "exact self-type" rule — List[S], Option[S], tuples of S, etc. are not descended in this version; their elements are leftover skeleton). For
enum Expr:
case Var(name: String) // 0 children
case App(f: Expr, x: Expr) // 2 children
case Lam(bind: String, body: Expr) // 1 child (bind:String is skeleton)
plate[Expr] gathers App's f/x and Lam's body, leaving Var.name / Lam.bind untouched. Works on Scala 3 enums, sealed hierarchies (via Hearth's Enum.parse), and plain recursive case classes (via CaseClass.parse). Reconstruction routes through CaseClass.construct[Id] (new V(...), never .copy), so enum cases reassemble fine.
children reads the self-typed fields in declaration order; rebuild swaps them back by the same declaration-order index, so the two agree without relying on construct's call order.
Attributes
- Source
- PlateMacro.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
PlateMacro.type
Compile-time derivation of a Prism from a sum / enum / union type S to a direct child A a: S. Macro-time validation checks A is a direct child of S.
Compile-time derivation of a Prism from a sum / enum / union type S to a direct child A a: S. Macro-time validation checks A is a direct child of S.
enum Shape:
case Circle(radius: Double)
case Square(side: Double)
val circleP = prism[Shape, Shape.Circle]
val intP = prism[Int | String, Int]
Attributes
- Source
- PrismMacro.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
PrismMacro.type