UnfoldLaws

dev.constructive.eo.laws.UnfoldLaws
trait UnfoldLaws[T, B, F[_]]

Law equations for an Unfold[T, B, F] — the build-only / many optic (Optic[Unit, T, Unit, B, Forget[F]] whose real map is embed: F[B] => T).

Like GetterLaws, the primary law is constructor-correctness: the only observable behaviour of a build-only optic is embed, so it must equal whatever reference function the caller claims the unfold represents. The two coherence laws pin the fused andThen members to their specification — post-composition through a Review re-homes the assembled whole ((rev ∘ u).embed = rev.reverseGet ∘ u.embed) and pre-composition maps each part ((u ∘ rev).embed = u.embed ∘ map(rev.reverseGet)) — so an algebra assembled by optic composition cannot drift from the functions it was assembled from.

vestigialSingleton applies only to Applicative-carrier unfolds (built via Unfold.apply): the vestigial read side is pure(()), so a modify round-trip must equal embedding the singleton layer. Pattern-functor unfolds (built via Unfold.algebra) have no lawful read side at all — their vestigial to throws by specification, which is a behaviour check, not a law (see UnfoldSpec).

Attributes

Source
UnfoldLaws.scala
Graph
Supertypes
class Object
trait Matchable
class Any

Members list

Value members

Abstract methods

def reference: F[B] => T

The function this unfold is declared to represent — typically the same F[B] => T passed to Unfold.apply / Unfold.algebra.

The function this unfold is declared to represent — typically the same F[B] => T passed to Unfold.apply / Unfold.algebra.

Attributes

Source
UnfoldLaws.scala
def unfold: Unfold[T, B, F]

The optic under test.

The optic under test.

Attributes

Source
UnfoldLaws.scala

Concrete methods

def embedConsistent(fb: F[B]): Boolean

unfold.embed(fb) equals the reference function applied at fb.

unfold.embed(fb) equals the reference function applied at fb.

Attributes

Source
UnfoldLaws.scala
def postComposeCoherent(f: T => Int, fb: F[B]): Boolean

Review(f).andThen(unfold) re-homes the whole: its embed is f ∘ embed.

Review(f).andThen(unfold) re-homes the whole: its embed is f ∘ embed.

Attributes

Source
UnfoldLaws.scala
def preComposeCoherent(g: Int => B, fi: F[Int])(using F: Functor[F]): Boolean

unfold.andThen(Review(g)) maps each part: its embed is embed ∘ map(g).

unfold.andThen(Review(g)) maps each part: its embed is embed ∘ map(g).

Attributes

Source
UnfoldLaws.scala
def vestigialSingleton(b: B)(using F: Applicative[F]): Boolean

Vestigial-read degradation for Applicative carriers: the modify round-trip through the vestigial to = pure(()) equals embedding the singleton layer.

Vestigial-read degradation for Applicative carriers: the modify round-trip through the vestigial to = pure(()) equals embedding the singleton layer.

Attributes

Source
UnfoldLaws.scala