dev.constructive.eo.data
Carriers — the F[_, _] shapes an optics.Optic's to / from run through: Direct (plain focus, no leftover), Either (prism miss), Affine (miss '''or''' hit-with-context), Forget / opaque ForgetK (read-only collapse), ModifyF (effectful write), MultiFocus / opaque MultiFocusK (many foci), plus the perf substrate (PSVec and the array builders). Each carrier's companion hosts its typeclass instances, so composition resolves with no imports.
Attributes
Members list
Type members
Classlikes
Carrier for the Optional family — sealed hierarchy: Affine.Miss (no focus; carries Fst[A]) and Affine.Hit (focus present; carries Snd[A] + B). Miss / Hit store fields directly (no Either / Tuple2 wrapper); a .affine: Either[Fst[A], (Snd[A], B)] legacy accessor reconstructs the old view on demand. Prefer matching Miss(...) / Hit(...) for zero-alloc access.
Carrier for the Optional family — sealed hierarchy: Affine.Miss (no focus; carries Fst[A]) and Affine.Hit (focus present; carries Snd[A] + B). Miss / Hit store fields directly (no Either / Tuple2 wrapper); a .affine: Either[Fst[A], (Snd[A], B)] legacy accessor reconstructs the old view on demand. Prefer matching Miss(...) / Hit(...) for zero-alloc access.
At every constructor site A is a concrete Tuple2 (so Fst[A] / Snd[A] reduce); when carried through an Optic[…, Affine] existential, A is abstract and the match types stay inert.
Type parameters
- A
-
existential leftover tuple
- B
-
focus type
Attributes
- Companion
- object
- Source
- Affine.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Known subtypes
Constructors and typeclass instances for Affine.
Constructors and typeclass instances for Affine.
Attributes
- Companion
- trait
- Source
- Affine.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Affine.type
Typeclass instances for Direct, plus the wrap / unwrap boundary. Every operation collapses to plain function application at runtime — zero per-call overhead beyond the user's function.
Typeclass instances for Direct, plus the wrap / unwrap boundary. Every operation collapses to plain function application at runtime — zero per-call overhead beyond the user's function.
Attributes
- Source
- Direct.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Direct.type
API façade under the carrier's public name. The instances live in ForgetK (the opaque anchor's companion, where implicit scope finds them); this re-export keeps Forget.assocFor call-shapes and legacy import data.Forget.given working.
API façade under the carrier's public name. The instances live in ForgetK (the opaque anchor's companion, where implicit scope finds them); this re-export keeps Forget.assocFor call-shapes and legacy import data.Forget.given working.
Attributes
- Source
- Forget.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Forget.type
Capability ladder for Forget. Each typeclass on F unlocks a matching optic operation:
Capability ladder for Forget. Each typeclass on F unlocks a matching optic operation:
F: Functor → ForgetfulFunctor[Forget[F]] → .modify / .replace
F: Foldable → ForgetfulFold[Forget[F]] → .foldMap
F: Traverse → ForgetfulTraverse[Forget[F], Applicative] → .modifyA, .all
F: Applicative → ForgetfulApplicative[Forget[F]] → .put
F: Monad → AssociativeFunctor[Forget[F], _, _] → same-carrier .andThen
(algebraic-lens shape)
Forget[F]'s X is phantom — Traversal / Fold need no outer-structural context on from. For cases where the outer's leftover must survive, use the pair carrier MultiFocus; Forget[F] injects trivially into it via Composer[Forget[F], MultiFocus[F]]. Direct-targeting instances live in Direct.
Attributes
- Source
- Forget.scala
- Supertypes
- Self type
-
ForgetK.type
Lower-priority instance drawer — holds the FlatMap + Comonad AssociativeFunctor which composes via coflatMap (parallel-fold semantics, genuinely different from the Monad-based algebraic-lens composition in ForgetK). Kept at lower priority so Monad wins when both apply.
Lower-priority instance drawer — holds the FlatMap + Comonad AssociativeFunctor which composes via coflatMap (parallel-fold semantics, genuinely different from the Monad-based algebraic-lens composition in ForgetK). Kept at lower priority so Monad wins when both apply.
Attributes
- Source
- Forget.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Known subtypes
-
object ForgetK
Typeclass instances for ModifyF.
Typeclass instances for ModifyF.
Attributes
- Companion
- class
- Source
- ModifyF.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
ModifyF.type
Carrier for the Modify family — pairs a source Fst[A] with a continuation Snd[A] => B.
Carrier for the Modify family — pairs a source Fst[A] with a continuation Snd[A] => B.
Same-carrier composition (modify.andThen(modify)) ships via ModifyF.assocModifyF — AssociativeFunctor[ModifyF, Xo, Xi] with type Z = (Fst[Xo], Snd[Xi]). The deferred-modify semantic fits the protocol once you observe that composeTo only needs to seed (xo, identity) (no inner-to call required, since ModifyF's continuation is structurally identity at every canonical construction site — coerceToModify and Modify.apply); composeFrom then extracts the user's c2d from the mapped continuation and routes it through inner.from then outer.from. The asInstanceOf casts inside the instance are sound under the universal convention that every ModifyF optic stores X = (S_outer, A_focus) (enforced at every construction site).
Type parameters
- A
-
existential leftover tuple
- B
-
focus written back
Attributes
- Companion
- object
- Source
- ModifyF.scala
- Supertypes
-
class AnyValtrait Matchableclass Any
API façade under the carrier's public name. The instances live in MultiFocusK (the opaque anchor's companion, where implicit scope finds them); this re-export keeps MultiFocus.apply / MultiFocus.fromLensF call-shapes and legacy import data.MultiFocus.given working.
API façade under the carrier's public name. The instances live in MultiFocusK (the opaque anchor's companion, where implicit scope finds them); this re-export keeps MultiFocus.apply / MultiFocus.fromLensF call-shapes and legacy import data.MultiFocus.given working.
Attributes
- Source
- MultiFocus.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
MultiFocus.type
Instance home for MultiFocusK — the capability instances (mfFunctor / mfFold / mfTraverse), the same-carrier composition kernels (mfAssoc and its Function1 / PSVec specialisations), the Composer bridges from every other carrier, the factories, and the .collect* / .at aggregation surface. Being the opaque anchor's companion, everything here is in implicit scope with no import; the public call-shape is the MultiFocus façade.
Instance home for MultiFocusK — the capability instances (mfFunctor / mfFold / mfTraverse), the same-carrier composition kernels (mfAssoc and its Function1 / PSVec specialisations), the Composer bridges from every other carrier, the factories, and the .collect* / .at aggregation surface. Being the opaque anchor's companion, everything here is in implicit scope with no import; the public call-shape is the MultiFocus façade.
Attributes
- Source
- MultiFocus.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
MultiFocusK.type
Constructors for PSVec — the primary entry points are empty, singleton, and unsafeWrap (zero-copy from an Array[AnyRef]). The three Slice / Single / Empty subclasses are internal to the dev.constructive.eo.data package and stable across release lines only at the aggregate PSVec supertype level.
Constructors for PSVec — the primary entry points are empty, singleton, and unsafeWrap (zero-copy from an Array[AnyRef]). The three Slice / Single / Empty subclasses are internal to the dev.constructive.eo.data package and stable across release lines only at the aggregate PSVec supertype level.
Attributes
- Companion
- trait
- Source
- PSVec.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
PSVec.type
Lightweight array-backed focus vector underlying MultiFocus[PSVec]. Three variants so empty and singleton focus vectors don't pay a backing-array allocation:
Lightweight array-backed focus vector underlying MultiFocus[PSVec]. Three variants so empty and singleton focus vectors don't pay a backing-array allocation:
- PSVec.Empty — shared singleton; Prism / Affine miss branches allocate nothing.
- PSVec.Single — element stored inline (~16 B vs a backing-array view's ~40 B).
- PSVec.Slice — arbitrary
(arr, offset, length)view. slice is a zero-copy pointer update — whatmfAssocPSVec.composeFromrelies on for O(1) per-element reassembly.
Equality is value-based across variants.
Attributes
- Companion
- object
- Source
- PSVec.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Known subtypes
Types
Identity carrier: Direct[X, A] = A (opaque). X is phantom. Used by Iso and Getter where the focus is fully determined and no reassembly information is needed — the optic's to / from are plain functions, so it is the forgetful functor (it forgets the leftover X entirely). Its instances therefore live under the Forgetful* typeclasses (forgetful.ForgetfulFunctor, forgetful.ForgetfulTraverse, …). The F-shape sibling Forget lives in its own file.
Identity carrier: Direct[X, A] = A (opaque). X is phantom. Used by Iso and Getter where the focus is fully determined and no reassembly information is needed — the optic's to / from are plain functions, so it is the forgetful functor (it forgets the leftover X entirely). Its instances therefore live under the Forgetful* typeclasses (forgetful.ForgetfulFunctor, forgetful.ForgetfulTraverse, …). The F-shape sibling Forget lives in its own file.
opaque (not a transparent alias) so it is a distinct type for implicit search: object Direct is its companion, so Accessor[Direct], AssociativeFunctor[Direct, …], etc. resolve via companion scope with no import, and the compiler never dealiases Direct[X, A] to A (which would lose those givens). It still erases to A, so Direct.apply (wrap) / value (unwrap) are identity at runtime.
Attributes
- Source
- Direct.scala
Curried carrier view of ForgetK — the F[_, _] shape Optic expects.
Adapt a F[_] container to the two-parameter carrier shape by wrapping it under the phantom X. Equivalent to the classic Haskell newtype Forget r a b = Forget (a -> r) construction but applied to a type constructor F: Forget[F][X, A] = F[A], ignoring X completely.
Adapt a F[_] container to the two-parameter carrier shape by wrapping it under the phantom X. Equivalent to the classic Haskell newtype Forget r a b = Forget (a -> r) construction but applied to a type constructor F: Forget[F][X, A] = F[A], ignoring X completely.
Used by dev.constructive.eo.optics.Fold (read-only), its build-only dual dev.constructive.eo.optics.Unfold, and the multi-focus family (dev.constructive.eo.data.MultiFocus) as a uniform "F-shape carrier" whose optic-level capabilities scale with the typeclasses F itself admits.
Attributes
- Source
- Forget.scala
Extract the first element type of a Tuple2. Stays as an unreduced match type when T is not a Tuple2 — this is load bearing for Affine.assoc accepting unbounded existentials.
Extract the first element type of a Tuple2. Stays as an unreduced match type when T is not a Tuple2 — this is load bearing for Affine.assoc accepting unbounded existentials.
Attributes
- Source
- Affine.scala
Curried carrier view of MultiFocusK — the F[_, _] shape Optic expects.
Curried carrier view of MultiFocusK — the F[_, _] shape Optic expects.
Attributes
- Source
- MultiFocus.scala
Unified pair carrier for the algebraic-lens, kaleidoscope, and grate optic families — MultiFocus[F][X, A] = (X, F[A]): a structural leftover X paired with a focus collection / aggregate / rebuild-closure F[A]. One carrier serves all three families; only the choice of F differs (a container for Traversal, Function1-shaped for the grate encoding, …).
Unified pair carrier for the algebraic-lens, kaleidoscope, and grate optic families — MultiFocus[F][X, A] = (X, F[A]): a structural leftover X paired with a focus collection / aggregate / rebuild-closure F[A]. One carrier serves all three families; only the choice of F differs (a container for Traversal, Function1-shaped for the grate encoding, …).
The kaleidoscope aggregation ("summarise the foci, write the summary back") has two natural derivations, and the choice is structural — not derivable from a single typeclass:
- Functor-broadcast:
fa.map(_ => f(fa)). Length-preserving; default. NeedsFunctor[F]. - Applicative-broadcast:
F.pure(f(fa)). Singleton/cartesian. NeedsApplicative[F].
The default is the first; List users wanting the singleton collapse can compose _.headOption downstream or call collectList explicitly. See docs/research/2026-04-29-fixedtraversal-fold-spike.md for the grate-absorption justification.
Type parameters
- F
-
classifier shape — operation requirements:
.modify/.replaceneedFunctor[F]..foldMapneedsFoldable[F]..modifyA/.allneedTraverse[F]..collectMap/.collectWithneedFunctor[F];collectListis List-specific.- Same-carrier
.andThenneedsTraverse[F] + MultiFocusFromList[F]. fromPrismF/fromOptionalFneedMonoidK[F].
Attributes
- Source
- MultiFocus.scala