Ana

dev.constructive.eo.schemes.zoo.Ana
final class Ana[F[_], Seed, S](val coalg: Seed => F[Seed])(using F: Traverse[F], E: Embed[F, S]) extends BuildScheme[S, Seed]

Anamorphism citizen — an unfold (BuildScheme) with X = S (the structure it threads). Carries coalg so cross can fuse with a node-blind Cata (→ Hylo) or a course-of-value Histo (→ Dyna). Refining X upward to Coattr = μX. Seed + F[X] (the free monad) gives the multi-layer unfold (futumorphism — Futu).

Attributes

Source
Ana.scala
Graph
Supertypes
class BuildScheme[S, Seed]
trait Optic[Unit, S, Unit, Seed, Direct]
class Object
trait Matchable
class Any

Members list

Grouped members

Operations

inline def cross[C, D](o: Optic[S, Unit, C, D, Direct])(using Accessor[Direct], ReverseAccessor[Direct]): Optic[Seed, Unit, C, D, Direct]

Build-then-observe across the build-output ⇄ read-input seam, preserving structure, on a shared carrier F. Flip self (it must be reversible — Accessor[F] and ReverseAccessor[F], i.e. an Iso or Review over Direct) so it reads T from B, then andThen that under the same carrier. The result is the full Optic[B, A, C, D, F], not a collapsed getter: its read capability follows the carrier (.get for Direct), and self's read focus A survives as the composite's write-back focus.

Build-then-observe across the build-output ⇄ read-input seam, preserving structure, on a shared carrier F. Flip self (it must be reversible — Accessor[F] and ReverseAccessor[F], i.e. an Iso or Review over Direct) so it reads T from B, then andThen that under the same carrier. The result is the full Optic[B, A, C, D, F], not a collapsed getter: its read capability follows the carrier (.get for Direct), and self's read focus A survives as the composite's write-back focus.

This is exactly self.reverse.andThen(that). The motivating case is ana.cross(cata): a Review (the unfold) crossed with a getter on the built S (the fold) — a (materializing) hylomorphism whose .get reads the folded value. When that sits on a different carrier (a Prism, a Fold, …), the cross-carrier cross overload below is selected instead.

Seam: that's source is self's T and its back-type is self's S.

Attributes

Inherited from:
Optic
Source
Optic.scala

Type members

Types

type X = S

Existential leftover carried alongside the focus — the type-level witness the carrier uses to rebuild T. Concrete at construction (Lens.apply sets X = S, Prism.apply sets X = S, …) and abstract when the optic is bound to Optic[…, F] without refinement.

Existential leftover carried alongside the focus — the type-level witness the carrier uses to rebuild T. Concrete at construction (Lens.apply sets X = S, Prism.apply sets X = S, …) and abstract when the optic is bound to Optic[…, F] without refinement.

Attributes

Source
Ana.scala

Value members

Concrete methods

def cross[B](cata: Cata[F, S, B]): Hylo[Seed, B]

The fused hylo seam: ana ∘ a node-blind Cata. Because the fold retains nothing (X = Nothing), deforestation is sound — the one-pass machine is rebuilt from coalg + cata.alg, building no intermediate S. A member (not the generic Optic.cross, which would reverse.andThen into a materialising read) so the fusion wins overload resolution.

The fused hylo seam: ana ∘ a node-blind Cata. Because the fold retains nothing (X = Nothing), deforestation is sound — the one-pass machine is rebuilt from coalg + cata.alg, building no intermediate S. A member (not the generic Optic.cross, which would reverse.andThen into a materialising read) so the fusion wins overload resolution.

Attributes

Source
Ana.scala
def cross[B](histo: Histo[F, S, B]): Dyna[Seed, B]

The fused dynamorphism seam: plain unfold ∘ course-of-value fold (Histo) — the refold-quadrant diagonal between cross's hylo and Futu.cross's chrono. Fuses; the Attr cofree memo is threaded internally, no intermediate S.

The fused dynamorphism seam: plain unfold ∘ course-of-value fold (Histo) — the refold-quadrant diagonal between cross's hylo and Futu.cross's chrono. Fuses; the Attr cofree memo is threaded internally, no intermediate S.

Attributes

Source
Ana.scala

Inherited methods

def andThen[C, IB, G[_, _]](inner: Optic[Unit, Unit, C, IB, G])(using rc: ReadCompose[Direct, G]): rc.Out[Unit, C]

ANY outer ∘ read-only inner — the inner is honestly one-way (T = Unit: a Getter, AffineFold, or Fold), so only the two READ sides matter and the composite collapses to the read-only join of their strengths via compose.ReadCompose (Getter / PickFold / ForgetFold).

ANY outer ∘ read-only inner — the inner is honestly one-way (T = Unit: a Getter, AffineFold, or Fold), so only the two READ sides matter and the composite collapses to the read-only join of their strengths via compose.ReadCompose (Getter / PickFold / ForgetFold).

A trait member (not an extension in the companion) deliberately: once a receiver is statically one of the fused concrete classes, its andThen member overloads enter resolution and Scala 3 never falls back to extension methods when they all fail — the collapse must be in the member overload set to be reachable without an expected-type ascription.

Only the inner's T is pinned to Unit; its B stays free (IB) even though read-only inners always have B = Unit. That keeps this overload strictly LESS specific than the same-carrier andThen above (which accepts every argument this one does whenever B = Unit at the receiver), so a same-carrier read-only ∘ read-only call resolves unambiguously to the AssociativeFunctor path and this one fires exactly on the cross-seam cells the generic member cannot type.

Attributes

Inherited from:
Optic
Source
Optic.scala
inline def andThen[C, D](o: Optic[Unit, Seed, C, D, Direct]): Optic[Unit, S, C, D, Direct]

Compose with another optic under the shared carrier F. Requires AssociativeFunctor[F]. Cross-carrier composition (Lens → Optional, Lens → Traversal, …) goes through the Morph-summoning overload of this same method.

Compose with another optic under the shared carrier F. Requires AssociativeFunctor[F]. Cross-carrier composition (Lens → Optional, Lens → Traversal, …) goes through the Morph-summoning overload of this same method.

Attributes

Example
case class Address(street: String)
case class Person(address: Address)
val streetLens = lens[Person](_.address).andThen(lens[Address](_.street))
Inherited from:
Optic
Source
Optic.scala
final def from(d: Direct[X, Seed]): S

Close the carrier: given a modified focus B (and the leftover X already inside the F), reassemble the result T.

Close the carrier: given a modified focus B (and the leftover X already inside the F), reassemble the result T.

Attributes

Inherited from:
BuildScheme
Source
SchemeShapes.scala
final def to(u: Unit): Direct[X, Unit]

Push the source S into the carrier, extracting the focus A and packing the leftover X. Paired with from to reconstruct T.

Push the source S into the carrier, extracting the focus A and packing the leftover X. Paired with from to reconstruct T.

Attributes

Inherited from:
BuildScheme
Source
SchemeShapes.scala