dev.constructive.eo.optics

The concrete optic zoo: Optic (the one existential base trait) and its named shapes — Lens, Prism, Iso, Optional, Traversal, Getter, Fold, AffineFold, Review, Modify, Unfold, Plated — each a thin class over a carrier from data with fused andThen overloads so hot compositions skip the generic seam. Construct and compose here; consume through the capability traits in dev.constructive.eo.

Attributes

Members list

Type members

Classlikes

object AffineFold

Constructors for AffineFold.

Constructors for AffineFold.

Attributes

Source
AffineFold.scala
Supertypes
class Object
trait Matchable
class Any
Self type
AffineFold.type
final class BijectionIso[S, T, A, B](read: S => A, build: B => T) extends Optic[S, T, A, B, Direct], CanGet[S, A], CanReverseGet[T, B], CanModifyP[S, T, A, B], CanFold[S, A]

Concrete Optic subclass for an isomorphism. Stores get / reverseGet directly so the hot path skips the Accessor[Direct] / ReverseAccessor[Direct] typeclass dispatches the generic extensions would perform — same storage shape as Monocle's Iso. Returned by Iso.apply so hand-written isos pick up the fused path automatically.

Concrete Optic subclass for an isomorphism. Stores get / reverseGet directly so the hot path skips the Accessor[Direct] / ReverseAccessor[Direct] typeclass dispatches the generic extensions would perform — same storage shape as Monocle's Iso. Returned by Iso.apply so hand-written isos pick up the fused path automatically.

Attributes

Source
Iso.scala
Supertypes
trait CanFold[S, A]
trait CanModifyP[S, T, A, B]
trait CanReverseGet[T, B]
trait CanGet[S, A]
trait Optic[S, T, A, B, Direct]
class Object
trait Matchable
class Any
Show all
object Fold

Constructors for Fold — read-only multi-focus optic, backed by Forget[F] (Forget[F][X, A] = F[A]). T = Unit rules out the write path; .foldMap is the consumption surface. Fold.select(p) narrows to a one-element Option stream. The build-only dual on the same carrier — assemble a T from an F-layer — is Unfold.

Constructors for Fold — read-only multi-focus optic, backed by Forget[F] (Forget[F][X, A] = F[A]). T = Unit rules out the write path; .foldMap is the consumption surface. Fold.select(p) narrows to a one-element Option stream. The build-only dual on the same carrier — assemble a T from an F-layer — is Unfold.

Both constructors return the concrete ForgetFold subclass so a hand-written Fold picks up its eager, carrier-free foldMap member (see ForgetFold.foldMap).

Attributes

Source
Fold.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Fold.type
final class ForgetFold[S, F[_], A](val read: S => F[A])(using FF: Foldable[F]) extends Optic[S, Unit, A, Unit, Forget[F]], CanFold[S, A]

Concrete Optic subclass for Fold, storing the source projection to and the underlying Foldable[F] directly. This lets the terminal foldMap fold the focus eagerly through the captured Foldable[F], skipping both the per-call ForgetfulFold[Forget[F]] summon and the intermediate S => M closure the generic Optic.foldMap extension builds — the same specialisation GetReplaceLens / Modify / MultiFocusSingleton apply to their hot paths.

Concrete Optic subclass for Fold, storing the source projection to and the underlying Foldable[F] directly. This lets the terminal foldMap fold the focus eagerly through the captured Foldable[F], skipping both the per-call ForgetfulFold[Forget[F]] summon and the intermediate S => M closure the generic Optic.foldMap extension builds — the same specialisation GetReplaceLens / Modify / MultiFocusSingleton apply to their hot paths.

Returned by every Fold.* constructor so hand-written folds pick up the fast path automatically. A composed Fold (the result of .andThen) surfaces as the erased Optic[…, Forget[F]] and keeps the generic extension — the same trade-off GetReplaceLens accepts.

Attributes

Source
Fold.scala
Supertypes
trait CanFold[S, A]
trait Optic[S, Unit, A, Unit, Forget[F]]
class Object
trait Matchable
class Any
class GetReplaceLens[S, T, A, B](read: S => A, val enplace: (S, B) => T) extends Optic[S, T, A, B, Tuple2], CanGet[S, A], CanModifyP[S, T, A, B], CanFold[S, A]

Concrete Optic subclass storing get and enplace directly, enabling the fused-andThen overloads below to bypass the Tuple2 carrier entirely. Returned by every Lens.* constructor so hand-written lenses pick up the fused hot path automatically.

Concrete Optic subclass storing get and enplace directly, enabling the fused-andThen overloads below to bypass the Tuple2 carrier entirely. Returned by every Lens.* constructor so hand-written lenses pick up the fused hot path automatically.

Attributes

Source
Lens.scala
Supertypes
trait CanFold[S, A]
trait CanModifyP[S, T, A, B]
trait CanGet[S, A]
trait Optic[S, T, A, B, Tuple2]
class Object
trait Matchable
class Any
Show all
final class Getter[S, A](read: S => A) extends Optic[S, Unit, A, Unit, Direct], CanGet[S, A], CanFold[S, A]

Concrete Optic subclass for a read-only getter. A final class storing get directly — NOT an abstract class with an abstract get: the CI A/B showed composed-getter dispatch through the abstract-class form costs ~1.8x (eoGet_3 5.1ns final vs 11.5ns abstract) even with a fused andThen, while every fused path that stayed a concrete class (GetReplaceLens lens-reuse) was flat. The hot path skips the Accessor[Direct] dispatch the generic extension would perform — the same shape as BijectionIso / GetReplaceLens. Returned by Getter.apply so hand-written getters pick up the fused path automatically.

Concrete Optic subclass for a read-only getter. A final class storing get directly — NOT an abstract class with an abstract get: the CI A/B showed composed-getter dispatch through the abstract-class form costs ~1.8x (eoGet_3 5.1ns final vs 11.5ns abstract) even with a fused andThen, while every fused path that stayed a concrete class (GetReplaceLens lens-reuse) was flat. The hot path skips the Accessor[Direct] dispatch the generic extension would perform — the same shape as BijectionIso / GetReplaceLens. Returned by Getter.apply so hand-written getters pick up the fused path automatically.

Attributes

Companion
object
Source
Getter.scala
Supertypes
trait CanFold[S, A]
trait CanGet[S, A]
trait Optic[S, Unit, A, Unit, Direct]
class Object
trait Matchable
class Any
Show all
object Getter

Constructor for Getter — read-only single-focus optic, backed by Direct with T = B = Unit. .get(s) is the only meaningful operation; the write path is vestigial.

Constructor for Getter — read-only single-focus optic, backed by Direct with T = B = Unit. .get(s) is the only meaningful operation; the write path is vestigial.

Both the leftover T and the back-focus B are Unit, which makes the read-only-ness explicit in the type (there is no B to put back). Getter.apply returns a concrete Getter, so a Getter composes with another Getter through the ordinary andThen (the fused Getter.andThen) — g1.andThen(g2) reads s => g2.get(g1.get(s)) — exactly as Iso / Lens compose via their own fused subclasses.

Attributes

Companion
class
Source
Getter.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Getter.type
object Iso

Constructor for Iso — a bijective single-focus optic, backed by Direct. An Iso[S, A] (short for Optic[S, S, A, A, Direct]) encodes a data-shape bijection. Direct[X, A] = A carries no leftover, so every Iso operation reduces to plain function application.

Constructor for Iso — a bijective single-focus optic, backed by Direct. An Iso[S, A] (short for Optic[S, S, A, A, Direct]) encodes a data-shape bijection. Direct[X, A] = A carries no leftover, so every Iso operation reduces to plain function application.

Attributes

Source
Iso.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Iso.type
object Lens

Constructors for Lens — the always-present single-focus optic, backed by Tuple2. A Lens[S, A] (short for Optic[S, S, A, A, Tuple2]) reads a field via get(s) and rewrites it via modify / replace. The eo-generics module's lens[S](_.field) macro derives both.

Constructors for Lens — the always-present single-focus optic, backed by Tuple2. A Lens[S, A] (short for Optic[S, S, A, A, Tuple2]) reads a field via get(s) and rewrites it via modify / replace. The eo-generics module's lens[S](_.field) macro derives both.

Attributes

Source
Lens.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Lens.type
final class MendTearPrism[S, T, A, B](val tear: S => Either[T, A], val mend: B => T) extends Optic[S, T, A, B, Either], CanGetOption[S, A], CanReverseGet[T, B], CanModifyP[S, T, A, B], CanFold[S, A]

Concrete Optic subclass storing tear (getOrModify) and mend (reverseGet) directly. The fused-andThen overloads pattern-match once and skip the generic AssociativeFunctor[Either] round-trip. All Prism.* constructors return this type.

Concrete Optic subclass storing tear (getOrModify) and mend (reverseGet) directly. The fused-andThen overloads pattern-match once and skip the generic AssociativeFunctor[Either] round-trip. All Prism.* constructors return this type.

Attributes

Source
Prism.scala
Supertypes
trait CanFold[S, A]
trait CanModifyP[S, T, A, B]
trait CanReverseGet[T, B]
trait CanGetOption[S, A]
trait Optic[S, T, A, B, Either]
class Object
trait Matchable
class Any
Show all
final class Modify[S, T, A, B](val modifyFn: (A => B) => S => T) extends Optic[S, T, A, B, ModifyF], CanModifyP[S, T, A, B]

Concrete Optic subclass for a write-only modifier. Stores the writer modifyFn directly (so the hot path skips the ModifyF carrier round-trip the generic extension performs) and carries a fused andThen for modify∘modify composition — the same shape as GetReplaceLens / Getter. Returned by Modify.apply so hand-written modifiers pick up the fused path automatically.

Concrete Optic subclass for a write-only modifier. Stores the writer modifyFn directly (so the hot path skips the ModifyF carrier round-trip the generic extension performs) and carries a fused andThen for modify∘modify composition — the same shape as GetReplaceLens / Getter. Returned by Modify.apply so hand-written modifiers pick up the fused path automatically.

Attributes

Companion
object
Source
Modify.scala
Supertypes
trait CanModifyP[S, T, A, B]
trait Optic[S, T, A, B, ModifyF]
class Object
trait Matchable
class Any
object Modify

Constructor for Modify — write-only single-focus optic, backed by ModifyF. The caller applies a function at the focus but cannot read it back; useful when observation would leak information or when the focus is genuinely unreadable (e.g. inside a closure).

Constructor for Modify — write-only single-focus optic, backed by ModifyF. The caller applies a function at the focus but cannot read it back; useful when observation would leak information or when the focus is genuinely unreadable (e.g. inside a closure).

Modify.apply returns a concrete Modify, so a Modify composes with another Modify through the ordinary andThen (the fused Modify.andThen) — s1.andThen(s2).modify(f) == s1.modify(s2.modify(f)) — exactly as Iso / Lens / Getter compose via their own fused subclasses, bypassing the generic AssociativeFunctor[ModifyF] round-trip.

Attributes

Companion
class
Source
Modify.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Modify.type
trait Optic[S, T, A, B, F[_, _]]

Existential encoding of a profunctor optic — the single trait behind every optic family in cats-eo. The optic is a pair of functions (S => F[X, A], F[X, B] => T) over a carrier F[_, _] and an existential X that threads the leftover information needed to rebuild T. Each family picks a different carrier (Tuple2 for Lens, Either for Prism, Affine for Optional, …). Operations live in the companion as capability-gated extensions; each extension's (using …) clause names the typeclass on F that unlocks it.

Existential encoding of a profunctor optic — the single trait behind every optic family in cats-eo. The optic is a pair of functions (S => F[X, A], F[X, B] => T) over a carrier F[_, _] and an existential X that threads the leftover information needed to rebuild T. Each family picks a different carrier (Tuple2 for Lens, Either for Prism, Affine for Optional, …). Operations live in the companion as capability-gated extensions; each extension's (using …) clause names the typeclass on F that unlocks it.

Type parameters

A

focus read out of S

B

focus written back to produce T (often = A)

F

two-argument carrier; capabilities scale with the typeclasses F admits.

S

source type being observed / modified

T

result type after modification (often = S)

Attributes

See also
Companion
object
Source
Optic.scala
Supertypes
class Object
trait Matchable
class Any
Known subtypes
class AvroBridge[A, B]
class AvroPrism[A]
class AvroRecordPrism[A]
class AvroTraversal[A]
class JsonPrism[A]
class BijectionIso[S, T, A, B]
class ForgetFold[S, F, A]
class GetReplaceLens[S, T, A, B]
class Getter[S, A]
class MendTearPrism[S, T, A, B]
class Modify[S, T, A, B]
class Optional[S, T, A, B]
class PickFold[S, A]
class PickMendPrism[S, A, B]
class Review[T, B]
class SplitCombineLens[S, T, A, B, XA]
class SimpleLens[S, A, XA]
class Unfold[T, B, F]
Show all
Self type
Optic[S, T, A, B, F]
object Optic

Companion for Optic. Hosts the profunctor instances and the capability-gated extension catalogue — .get, .modify, .replace, .foldMap, .modifyA, .all, .reverseGet, .getOption, .put, .transform, .place, .transfer, .andThen (carrier-morphing plus the read-only / AffineFold / Modify / Review / Unfold collapses), .readOnly, .cross, .morph, .headOption, .length, .exists. Adding a new carrier means supplying the typeclass instances of the operations it should support.

Companion for Optic. Hosts the profunctor instances and the capability-gated extension catalogue — .get, .modify, .replace, .foldMap, .modifyA, .all, .reverseGet, .getOption, .put, .transform, .place, .transfer, .andThen (carrier-morphing plus the read-only / AffineFold / Modify / Review / Unfold collapses), .readOnly, .cross, .morph, .headOption, .length, .exists. Adding a new carrier means supplying the typeclass instances of the operations it should support.

Attributes

Companion
trait
Source
Optic.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Optic.type
object Optional

Constructor for Optional — the conditionally-present single-focus optic, backed by Affine. An Optional[S, A] (short for Optic[S, S, A, A, Affine]) encodes a field that may or may not be there. Composes freely with Lens via cross-carrier .andThen (auto-morphs through Composer[Tuple2, Affine]).

Constructor for Optional — the conditionally-present single-focus optic, backed by Affine. An Optional[S, A] (short for Optic[S, S, A, A, Affine]) encodes a field that may or may not be there. Composes freely with Lens via cross-carrier .andThen (auto-morphs through Composer[Tuple2, Affine]).

Attributes

Companion
class
Source
Optional.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Optional.type
final class Optional[S, T, A, B](val getOrModify: S => Either[T, A], val reverseGet: (S, B) => T) extends Optic[S, T, A, B, Affine], CanGetOption[S, A], CanModifyP[S, T, A, B], CanFold[S, A]

Concrete Optic subclass for Optional.apply — stores getOrModify / reverseGet directly so the fused .andThen overloads can skip the generic AssociativeFunctor[Affine] round-trip whenever the other side is also a known subclass.

Concrete Optic subclass for Optional.apply — stores getOrModify / reverseGet directly so the fused .andThen overloads can skip the generic AssociativeFunctor[Affine] round-trip whenever the other side is also a known subclass.

Attributes

Companion
object
Source
Optional.scala
Supertypes
trait CanFold[S, A]
trait CanModifyP[S, T, A, B]
trait CanGetOption[S, A]
trait Optic[S, T, A, B, Affine]
class Object
trait Matchable
class Any
Show all
final class PickFold[S, A](val pick: S => Option[A]) extends Optic[S, Unit, A, Unit, Affine], CanGetOption[S, A], CanFold[S, A]

Concrete Optic subclass for AffineFold — a final class storing pick directly, NOT a shared anonymous wrapper: a single anon class would host one pick.apply bytecode site for every AffineFold instance, the megamorphic-dispatch trap PrintInlining exposed on the abstract-class Getter (the JIT profiles that one site over all instances' lambdas and gives up inlining). Same storage shape as PickMendPrism (pick) and ForgetFold (read). Returned by AffineFold.apply / AffineFold.select so hand-written affine folds pick up the fused members automatically.

Concrete Optic subclass for AffineFold — a final class storing pick directly, NOT a shared anonymous wrapper: a single anon class would host one pick.apply bytecode site for every AffineFold instance, the megamorphic-dispatch trap PrintInlining exposed on the abstract-class Getter (the JIT profiles that one site over all instances' lambdas and gives up inlining). Same storage shape as PickMendPrism (pick) and ForgetFold (read). Returned by AffineFold.apply / AffineFold.select so hand-written affine folds pick up the fused members automatically.

Attributes

Source
AffineFold.scala
Supertypes
trait CanFold[S, A]
trait CanGetOption[S, A]
trait Optic[S, Unit, A, Unit, Affine]
class Object
trait Matchable
class Any
Show all
final class PickMendPrism[S, A, B](val pick: S => Option[A], val mend: B => S) extends Optic[S, S, A, B, Either], CanGetOption[S, A], CanReverseGet[S, B], CanModifyP[S, S, A, B], CanFold[S, A]

Concrete Optic subclass for the Option-shaped Prism (Prism.optional / Prism.pOptional). Stores pick and mend directly; the fused extensions pattern-match on Option so the hot path never builds the intermediate Either[S, A] the generic MendTearPrism would.

Concrete Optic subclass for the Option-shaped Prism (Prism.optional / Prism.pOptional). Stores pick and mend directly; the fused extensions pattern-match on Option so the hot path never builds the intermediate Either[S, A] the generic MendTearPrism would.

Attributes

Source
Prism.scala
Supertypes
trait CanFold[S, A]
trait CanModifyP[S, S, A, B]
trait CanReverseGet[S, B]
trait CanGetOption[S, A]
trait Optic[S, S, A, B, Either]
class Object
trait Matchable
class Any
Show all
trait Plated[S]

A self-similar structure: a value of S whose immediate sub-terms are themselves S. The single member plate is a Traversal[S, S] focusing those immediate children — the cats-eo analogue of Haskell lens's Plated class (plate :: Traversal' a a).

A self-similar structure: a value of S whose immediate sub-terms are themselves S. The single member plate is a Traversal[S, S] focusing those immediate children — the cats-eo analogue of Haskell lens's Plated class (plate :: Traversal' a a).

The recursion combinators in the companion (Plated.transform, Plated.rewrite, Plated.children, Plated.universe) build on plate to walk the whole tree. They are stack-safe on deep trees: transform recurses on the call stack while shallow and falls back to a heap-stack machine past a depth bound, rewrite trampolines through cats.Eval, and universe / children use an explicit worklist — a degenerate 100k-deep tree is fine.

The children are carried as a PSVec (the MultiFocus[PSVec] carrier's focus vector), so the read path and the write path share one representation with no List round-trips — see childrenVec.

Get an instance by hand via Plated.fromChildren / Plated.fromChildrenVec, by deriving one with dev.constructive.eo.generics.plate[S], or — when you have already built the self-traversal as an optic — by calling .asPlated on it (see the extension methods below).

Attributes

See also

Traversal.selfChildren for the underlying carrier.

Companion
object
Source
Plated.scala
Supertypes
class Object
trait Matchable
class Any
object Plated

Combinators over Plated — recursion schemes faithful to Control.Lens.Plated, all stack-safe. Each is offered both as a using Plated[S] method here and as an extension on any self-traversal optic you build directly (so myPlate.transformAll(f)(s) works without a typeclass).

Combinators over Plated — recursion schemes faithful to Control.Lens.Plated, all stack-safe. Each is offered both as a using Plated[S] method here and as an extension on any self-traversal optic you build directly (so myPlate.transformAll(f)(s) works without a typeclass).

Attributes

Companion
trait
Source
Plated.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Plated.type
object Prism

Constructors for Prism — the partial single-focus optic, backed by Either. A Prism[S, A] (short for Optic[S, S, A, A, Either]) encodes a branch of a sum type: getOption(s) succeeds when s matches, reverseGet(a) lifts back. The eo-generics module's prism[S, A] macro derives prisms on enums / sealed traits / union types.

Constructors for Prism — the partial single-focus optic, backed by Either. A Prism[S, A] (short for Optic[S, S, A, A, Either]) encodes a branch of a sum type: getOption(s) succeeds when s matches, reverseGet(a) lifts back. The eo-generics module's prism[S, A] macro derives prisms on enums / sealed traits / union types.

Attributes

Source
Prism.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Prism.type
final class Review[T, B](build: B => T) extends Optic[Unit, T, Unit, B, Direct], CanReverseGet[T, B]

Reverse-only counterpart to Getter — wraps reverseGet: A => S and is the exact mirror of Getter. Getter is Optic[S, Unit, A, Unit, Direct] (a real to reading S => A, vestigial from); Review is the dual Optic[Unit, S, Unit, A, Direct] — a vestigial to (reads Unit) and a real from that builds S from the focus A.

Reverse-only counterpart to Getter — wraps reverseGet: A => S and is the exact mirror of Getter. Getter is Optic[S, Unit, A, Unit, Direct] (a real to reading S => A, vestigial from); Review is the dual Optic[Unit, S, Unit, A, Direct] — a vestigial to (reads Unit) and a real from that builds S from the focus A.

It therefore IS an Optic — with source Unit the to is exactly as vestigial as Getter's from, so "pure Review has no to" is no reason to sit outside the trait. A Review composes with another Review through the fused andThen just as Getters do, and slots into the Direct-carrier optic surface.

A final class storing reverseGet directly — NOT an abstract class with an abstract member — for the same composed-dispatch reason documented on Getter.

To get the build direction out of an Iso or Prism, wrap its reverse directly — Review(iso.reverseGet) / Review(prism.mend) — rather than via a bespoke factory: an Iso/Prism already is a build direction, so cross-optic from* constructors would be redundant (eo has no Prism.fromIso etc. for the same reason).

Review builds from ONE focus; its many-rung sibling is Unfold (assemble a T from an F-layer of parts), reachable by composition through the fused andThen(Unfold) below.

Attributes

Companion
object
Source
Review.scala
Supertypes
trait CanReverseGet[T, B]
trait Optic[Unit, T, Unit, B, Direct]
class Object
trait Matchable
class Any
object Review

Constructors for Review.

Constructors for Review.

Attributes

Companion
class
Source
Review.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Review.type
final class SimpleLens[S, A, XA](get: S => A, split: S => (XA, A), combine: (XA, A) => S) extends SplitCombineLens[S, S, A, A, XA]

Monomorphic split-combine lens (S = T, A = B). The matched source / target lets the to splitter double as the T => (X, A) evidence the mutation extensions need, so place / transfer land on the class body directly. Used by Lens.first, Lens.second, and the eo-generics lens[S](_.field) macro.

Monomorphic split-combine lens (S = T, A = B). The matched source / target lets the to splitter double as the T => (X, A) evidence the mutation extensions need, so place / transfer land on the class body directly. Used by Lens.first, Lens.second, and the eo-generics lens[S](_.field) macro.

Attributes

Companion
object
Source
Lens.scala
Supertypes
class SplitCombineLens[S, S, A, A, XA]
trait CanFold[S, A]
trait CanModifyP[S, S, A, A]
trait CanGet[S, A]
trait Optic[S, S, A, A, Tuple2]
class Object
trait Matchable
class Any
Show all
object SimpleLens

Companion for SimpleLens. Hands out a transformEvidence given so the generic Optic.transform / .place / .transfer extensions pick up the same behaviour as the class-level methods.

Companion for SimpleLens. Hands out a transformEvidence given so the generic Optic.transform / .place / .transfer extensions pick up the same behaviour as the class-level methods.

Attributes

Companion
class
Source
Lens.scala
Supertypes
class Object
trait Matchable
class Any
Self type
SimpleLens.type
class SplitCombineLens[S, T, A, B, XA](read: S => A, val split: S => (XA, A), val combine: (XA, B) => T) extends Optic[S, T, A, B, Tuple2], CanGet[S, A], CanModifyP[S, T, A, B], CanFold[S, A]

Polymorphic split-combine lens — splitter S => (XA, A) + combiner (XA, B) => T, surfacing the complement as X = XA. Does not ship place / transfer (would require a T => (XA, B) evidence that isn't recoverable when T ≠ S); callers route through the generic Optic extensions when the evidence is available.

Polymorphic split-combine lens — splitter S => (XA, A) + combiner (XA, B) => T, surfacing the complement as X = XA. Does not ship place / transfer (would require a T => (XA, B) evidence that isn't recoverable when T ≠ S); callers route through the generic Optic extensions when the evidence is available.

Attributes

Source
Lens.scala
Supertypes
trait CanFold[S, A]
trait CanModifyP[S, T, A, B]
trait CanGet[S, A]
trait Optic[S, T, A, B, Tuple2]
class Object
trait Matchable
class Any
Show all
Known subtypes
class SimpleLens[S, A, XA]
object Traversal

Constructors for Traversal. Every constructor here — each / pEach / selfChildren and the two / three / four fixed-arity variants — rides the MultiFocus[PSVec] carrier, so they all compose through the standard .andThen in both directions (past a Lens, a Prism, another traversal, …).

Constructors for Traversal. Every constructor here — each / pEach / selfChildren and the two / three / four fixed-arity variants — rides the MultiFocus[PSVec] carrier, so they all compose through the standard .andThen in both directions (past a Lens, a Prism, another traversal, …).

Attributes

Source
Traversal.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Traversal.type
final class Unfold[T, B, F[_]] extends Optic[Unit, T, Unit, B, Forget[F]]

Build-only counterpart to Fold — the inhabitant of the build-only / many cell of the optic lattice, exactly as Review is Getter's build-only mirror on the total rung. Fold is Optic[S, Unit, A, Unit, Forget[F]] (a real to reading S => F[A], vestigial from); Unfold is the across-both-axes dual Optic[Unit, T, Unit, B, Forget[F]] — a vestigial to and a real from that assembles one T from a layer of parts F[B]:

Build-only counterpart to Fold — the inhabitant of the build-only / many cell of the optic lattice, exactly as Review is Getter's build-only mirror on the total rung. Fold is Optic[S, Unit, A, Unit, Forget[F]] (a real to reading S => F[A], vestigial from); Unfold is the across-both-axes dual Optic[Unit, T, Unit, B, Forget[F]] — a vestigial to and a real from that assembles one T from a layer of parts F[B]:

 embed :  F[B] => T        // many → one: the algebra of a recursion scheme

This is the F-shape embed of a Corecursive instance (Fold's S => F[A] being the project half), and the aggregation arrow "build an Order from its line-items". Plated's plate bundles both halves inside one read-write traversal; Unfold exposes the embed half standalone, so an algebra can be carried, composed, and consumed as an optic.

'''The vestigial to.''' Read-only optics zero out their write side for free (from discards into Unit, the terminal object). The build-only dual is not free: to: Unit => F[Unit] must produce an F-layer, and there is no canonical F[Unit] without Applicative[F] (pure(())). Two constructors, two answers:

  • Unfold.apply (F: Applicative) — honest vestigial to = pure(()). Read-side operations that reach to (.modify, .foldMap, …) degrade to the singleton layer.
  • Unfold.algebra (no constraint) — for pattern functors (BinF, RoseF, …), which admit Functor/Traverse but no Applicative (pure cannot pick a constructor). Its to is genuinely unreachable through the build-only surface and THROWS if forced — the same reachable-path contract as Composer.direct2forget's singleton-pick from.

A final class storing embed directly — NOT an abstract member — per the composed-dispatch findings on Getter / Review. Fused andThen members keep build-only chains concrete.

Attributes

Companion
object
Source
Unfold.scala
Supertypes
trait Optic[Unit, T, Unit, B, Forget[F]]
class Object
trait Matchable
class Any
object Unfold

Constructors for Unfold — build-only multi-focus optic, backed by Forget[F] (Forget[F][X, B] = F[B]) with S = A = Unit ruling out the read path; .embed is the consumption surface.

Constructors for Unfold — build-only multi-focus optic, backed by Forget[F] (Forget[F][X, B] = F[B]) with S = A = Unit ruling out the read path; .embed is the consumption surface.

Attributes

Companion
class
Source
Unfold.scala
Supertypes
class Object
trait Matchable
class Any
Self type
Unfold.type

Types

type AffineFold[S, A] = Optic[S, Unit, A, Unit, Affine]

Read-only 0-or-1-focus optic — Optic[S, Unit, A, Unit, Affine]. Both T and the write-focus B are Unit (honestly one-way, like Getter / Fold): there is no value to put back, so .modify / .replace don't apply. The surface is .getOption and .foldMap. Composes with Lens / Prism via the same Morph bridges full Optional uses (they key off the carrier, not the T slot).

Read-only 0-or-1-focus optic — Optic[S, Unit, A, Unit, Affine]. Both T and the write-focus B are Unit (honestly one-way, like Getter / Fold): there is no value to put back, so .modify / .replace don't apply. The surface is .getOption and .foldMap. Composes with Lens / Prism via the same Morph bridges full Optional uses (they key off the carrier, not the T slot).

Specialised existential X = (Unit, Unit): Affine.Hit stores snd: Unit + b: A — one reference slot less than the (S, A) payload of a full Optional, since from throws its input away anyway.

Attributes

Source
AffineFold.scala