proarrow
Safe HaskellNone
LanguageGHC2024

Proarrow.Optics

Description

The user-facing optics vocabulary, in one import.

The full subtyping lattice (flavor superclass edges, weakest optics at the top). Dotted nodes are one-sided flavors, whose methods never mention the second witness; dashed nodes are indexed by a monad and so have no edge to Iso:

Synopsis

Optic kinds

type Optic (c :: (j +-> k) -> Constraint) (s :: k) (t :: j) (a :: k) (b :: j) = Optic_ ('OPT a b :: OPTIC j k c) ('OPT s t :: OPTIC j k c) Source Github #

type Optic' (c :: (j +-> j) -> Constraint) (s :: j) (a :: j) = Optic c s s a a Source Github #

type Iso (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (IsoFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

The Prostrong-flavored iso; for the profunctor-class-flavored encoding see PIso.

type Iso' (s :: k) (a :: k) = Iso s s a a Source Github #

type Lens (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (LensFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type Lens' (s :: k) (a :: k) = Lens s s a a Source Github #

type MonoidalLens (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (MonLensFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type MonoidalLens' (s :: k) (a :: k) = MonoidalLens s s a a Source Github #

type Prism (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (PrismFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type Prism' (s :: k) (a :: k) = Prism s s a a Source Github #

type AffineTraversal (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (AffineTravFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type AffineTraversal' (s :: k) (a :: k) = AffineTraversal s s a a Source Github #

type Traversal (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (TravFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type Traversal' (s :: k) (a :: k) = Traversal s s a a Source Github #

type MonoidalTraversal (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (MonTravFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type MonoidalTraversal' (s :: k) (a :: k) = MonoidalTraversal s s a a Source Github #

type PTraversal (s :: j) (t :: j) (a :: j) (b :: j) = Optic (StrongDistributiveProfunctor :: (j +-> j) -> Constraint) s t a b Source Github #

A traversal in the profunctor-class-flavored encoding (cf. PIso), used by the GHC.Generics combinators below. Equivalent to Traversal via toPTraversal and fromPTraversal.

type PTraversal' (s :: j) (a :: j) = PTraversal s s a a Source Github #

type PTraversalFull (s :: j) (t :: j) (a :: j) (b :: j) = Optic ((StrongDistributiveProfunctor :: (j +-> j) -> Constraint) :&&: Strong (ProdAction :: j -> (PROD j, j) -> Type)) s t a b Source Github #

A full traversal in the profunctor-class encoding: distributes any profunctor carrying both distributive strength and product strength -- exactly the constraint travP demands. This is the Traversal analog of PTraversal, which drops the product strength (all it needs for a MonoidalTraversal). Equivalent to Traversal via toPTraversalFull and traversal.

type Setter (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (SetterFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type Setter' (s :: k) (a :: k) = Setter s s a a Source Github #

type Getter (s :: k) (t :: j) (a :: k) (b :: j) = Optic (Prostrong (GetterFl :: (k +-> k) -> (j +-> j) -> Constraint)) s t a b Source Github #

type Review (s :: k) (t :: j) (a :: k) (b :: j) = Optic (Prostrong (Flip (GetterFl :: (j +-> j) -> (k +-> k) -> Constraint))) s t a b Source Github #

type AffineFold (s :: k) (t :: j) (a :: k) (b :: j) = Optic (Prostrong (AffineFoldFl :: (k +-> k) -> (j +-> j) -> Constraint)) s t a b Source Github #

type Fold (s :: k) (t :: j) (a :: k) (b :: j) = Optic (Prostrong (FoldFl :: (k +-> k) -> (j +-> j) -> Constraint)) s t a b Source Github #

type Grate (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (GrateFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type Grate' (s :: k) (a :: k) = Grate s s a a Source Github #

type Glass (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (GlassFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type Glass' (s :: k) (a :: k) = Glass s s a a Source Github #

type PowerGrate (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (PowerGrateFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type PowerGrate' (s :: k) (a :: k) = PowerGrate s s a a Source Github #

type Cotraversal (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (CotravFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type Cotraversal' (s :: k) (a :: k) = Cotraversal s s a a Source Github #

type Kaleidoscope (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (KaleidoFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type Kaleidoscope' (s :: k) (a :: k) = Kaleidoscope s s a a Source Github #

type AlgebraicLens (m :: k +-> k) (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (AlgLensFl m)) s t a b Source Github #

An algebraic lens: like a Lens, but put is allowed to combine information monadically -- get :: s ~> a, put :: m % s ** b ~> t -- rather than only ever seeing the last s.

type ClassifyingLens (l :: k +-> k) (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (ClassifyFl l)) s t a b Source Github #

type Tracer (s :: k) (t :: k) (a :: k) (b :: k) = Optic (Prostrong (TracerFl :: (k +-> k) -> (k +-> k) -> Constraint)) s t a b Source Github #

type Tracer' (s :: k) (a :: k) = Tracer s s a a Source Github #

Building optics

iso :: forall {j} {k} (c :: (j +-> k) -> Constraint) (s :: k) (t :: j) (a :: k) (b :: j). (CategoryOf j, CategoryOf k) => (s ~> a) -> (b ~> t) -> Optic c s t a b Source Github #

Create an isomorphism from two arrows, at any optic constraint. Note that this doesn't enforce that the arrows are actually inverses!

The same iso builds a Iso, a PIso, a PTraversal, ... depending on the type it is used at; since c is only determined by the use site, bind the result with a type signature.

lens :: forall {k} (s :: k) (t :: k) (a :: k) (b :: k). (HasBinaryProducts k, Ob b) => (s ~> a) -> ((s && b) ~> t) -> Lens s t a b Source Github #

monLens :: forall {k} (m :: k) (s :: k) (t :: k) (a :: k) (b :: k). (Comonoid m, Ob a, Ob b) => (s ~> (m ** a)) -> ((m ** b) ~> t) -> MonoidalLens s t a b Source Github #

Build a monoidal lens from its two legs and a chosen comonoidal residual m.

prism :: forall {k} (s :: k) (t :: k) (a :: k) (b :: k). (CopyDiscard k, HasCoproducts k, Ob a) => (b ~> t) -> (s ~> (t || a)) -> Prism s t a b Source Github #

affineTraversal :: forall {k} (s :: k) (t :: k) (x :: k) (y :: k) (a :: k) (b :: k). CategoryOf k => Lens s t x y -> Prism x y a b -> AffineTraversal s t a b Source Github #

Build an AffineTraversal by composing a Lens with a Prism: focus a field with the lens, then match a case of that field with the prism. There is no from-legs builder for a bare affine traversal (its witness only ever arises by composition), so this is the design-aligned way to make one -- the same convert (l % p) idiom the test suite uses.

grate :: forall {k} (s :: k) (t :: k) (a :: k) (b :: k). (Closed k, SymMonoidal k, HasCoproducts k, Comonoid (s ~~> a), Ob s, Ob a, Ob b) => (((s ~~> a) ~~> b) ~> t) -> Grate s t a b Source Github #

The canonical/atomic grate constructor: the residual is the self-referential s ~~> a (the "logarithm" of the get side), whose own get-map m ~> (s ~~> a) trivializes to id once m is fixed to be exactly s ~~> a. That residual must be a comonoid; in a CopyDiscard category every object is.

glass :: forall {k} (s :: k) (t :: k) (a :: k) (b :: k). (CCC k, Ob s, Ob a, Ob b) => ((s && ((s ~~> a) ~~> b)) ~> t) -> Glass s t a b Source Github #

Build a glass from its single leg. The residuals are the whole source and the "logarithm" s ~~> a, so the witness is the lens witness at s composed with the grate witness at s ~~> a.

powerGrate :: forall {k} (n :: Nat) (s :: k) (t :: k) (a :: k) (b :: k). (CopyDiscard k, HasCoproducts k, KnownNat n, Ob a, Ob b) => (s ~> Tensor n a) -> (Tensor n b ~> t) -> PowerGrate s t a b Source Github #

Build an n-ary power grate from a tensor-power decomposition of s and recomposition of t.

cotraversal :: forall {k} (p :: k +-> k) (s :: k) (t :: k) (a :: k) (b :: k). (Representable p, StrongDistributiveProfunctor p, Ob a, Ob b) => (s ~> (p % a)) -> ((p % b) ~> t) -> Cotraversal s t a b Source Github #

Build a cotraversal from its legs through an applicative functor, given as a representable StrongDistributiveProfunctor p.

kaleidoscope :: forall {k} (p :: k +-> k) (s :: k) (t :: k) (a :: k) (b :: k). (Representable p, StrongDistributiveProfunctor p, Ob a, Ob b) => (s ~> (p % a)) -> ((p % b) ~> t) -> Kaleidoscope s t a b Source Github #

Build a kaleidoscope from the same legs.

algebraicLens :: forall {k} (m :: k +-> k) (s :: k) (t :: k) (a :: k) (b :: k). (Algebra m (m % s), Comonoid (m % s), Comonoid s, OplaxMonoidalRep m, Ob a, Ob b) => (s ~> a) -> (((m % s) ** b) ~> t) -> AlgebraicLens m s t a b Source Github #

Build an algebraic lens from get and a monadic put; the residual is the free algebra m % s itself (which must be a comonoid, as must s to be kept alongside its focus).

classifyingLens :: forall {k} (l :: k +-> k) (s :: k) (t :: k) (a :: k) (b :: k). (Algebra l (l % s), Monoid (l % s), Comonoid (l % s), Comonoid s, OplaxMonoidalRep l, SymMonoidal k, HasCoproducts k, Ob a, Ob b) => (s ~> a) -> (((l % s) ** b) ~> t) -> ClassifyingLens l s t a b Source Github #

Build a classifying lens from get and a classify :: l % s ** b ~> t; the residual is the free algebra l % s, e.g. the list of sources.

tracer :: forall {k} (m :: k) (s :: k) (t :: k) (a :: k) (b :: k). (TracedMonoidal k, Ob m, Ob s, Ob t, Ob a, Ob b) => ((m ** s) ~> a) -> (b ~> (m ** t)) -> Tracer s t a b Source Github #

Build a tracer from its two legs and a chosen residual m: m ** s ~> a decomposes the source (given the residual), b ~> m ** t rebuilds the target and produces the residual to feed back.

traversed :: forall {k} (t :: k +-> k) (a :: k) (b :: k). (Bicartesian k, Traversable t, Representable t, Ob a, Ob b) => Traversal (t % a) (t % b) a b Source Github #

Build a traversal from a Traversable (representable) functor t: it focuses every element the functor holds. This is the one weak-flavor builder that is genuinely primitive -- a Traversables traversal is not reachable by convert from any single stronger optic. The witness is t itself paired with RepCostar t (see TravFl above); the two legs are the representable universal repUniv and the identity RepCostar.

traversal :: forall {k} (s :: k) (t :: k) (a :: k) (b :: k). (Distributive k, CopyDiscard k, SymMonoidal k, HasProducts k, Ob a, Ob b, Ob s, Ob t) => (forall (r :: k +-> k). (StrongDistributiveProfunctor r, Strong (ProdAction :: k -> (PROD k, k) -> Type) r) => r a b -> r s t) -> Traversal s t a b Source Github #

Build a Traversal from its van-Laarhoven / profunctor-class form, by instantiating the rank-2 function at the generic carrier ExOptic TravFl a b (a StrongDistributiveProfunctor and Strong ProdAction, unlike ExOptic MonTravFl a b, since TravFl contains the product-lens witness). The Traversal analog of fromPTraversal.

to :: forall {k} {j} (s :: k) (t :: j) (a :: k) (b :: j). (CategoryOf k, CategoryOf j, Ob b, Ob t) => (s ~> a) -> Getter s t a b Source Github #

unto :: forall {k} {j} (s :: k) (t :: j) (a :: k) (b :: j). (CategoryOf k, CategoryOf j, Ob s, Ob a) => (b ~> t) -> Review s t a b Source Github #

re :: forall {j} {k} (a :: j) (b :: k) (c :: (k +-> j) -> Constraint) (coc :: (j +-> k) -> Constraint) (s :: j) (t :: k). (Ob a, Ob b, ReversibleOptic c coc) => Optic c s t a b -> Optic coc b a t s Source Github #

Eliminating optics

Exactly one eliminator per flavor: view, review, preview, over, foldMapOf, traverseOf, monTraverseOf, powerGrateOf, cotraverseOf, kaleidoscopeOf, zipWithOf, classifyOf and tracerOf run the optic; withIso, withLens, withMonLens, withPrism and withGrate recover its two legs.

view :: forall {j} {k} (c :: (k -> j -> Type) -> Constraint) (s :: k) (t :: j) (a :: k) (b :: j). (CategoryOf j, CategoryOf k, (Ob a, Ob b) => c (ExOptic (GetterFl :: (k +-> k) -> (j +-> j) -> Constraint) a b)) => Optic c s t a b -> s ~> a Source Github #

View through any optic that can act as a getter, in either encoding: run it at its witness pair (ExOptic GetterFl, via withLegs) and read the get leg off with getP.

review :: forall {j} {k} (c :: (k -> j -> Type) -> Constraint) (s :: k) (t :: j) (a :: k) (b :: j). (CategoryOf j, CategoryOf k, (Ob a, Ob b) => c (ExOptic (Flip (GetterFl :: (j +-> j) -> (k +-> k) -> Constraint)) a b)) => Optic c s t a b -> b ~> t Source Github #

Review through any optic that can act as a review, in either encoding: getP on the flipped witness pair.

preview :: forall {j} {k} (c :: (k -> j -> Type) -> Constraint) (s :: k) (t :: j) (a :: k) (b :: j). (Bicartesian k, CategoryOf j, (Ob a, Ob b) => c (ExOptic (AffineFoldFl :: (k +-> k) -> (j +-> j) -> Constraint) a b)) => Optic c s t a b -> s ~> (a || (TerminalObject :: k)) Source Github #

Preview through any optic that can act as an affine fold, in either encoding: run it at its witness pair (ExOptic AffineFoldFl, via withLegs) and apply previewP.

matching :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k). (Bicartesian k, (Ob a, Ob b) => c (ExOptic (AffineTravFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> s ~> (t || a) Source Github #

Match through any optic that can act as an affine traversal, in either encoding: returns the focus (rgt) when it matches, or a reconstructed t (lft) when it does not. This is the AffineTraversal eliminator, refining preview (which forgets t). Runs the optic at its witness pair (ExOptic AffineTravFl, via withLegs) and applies affineMatch.

over :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k). (CategoryOf k, (Ob a, Ob b) => c (ExOptic (SetterFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> (a ~> b) -> s ~> t Source Github #

Map over any optic that can act as a setter, in either encoding: run it at its witness pair (ExOptic SetterFl, via withLegs) and apply overP.

foldMapOf :: forall {j} {k} (c :: (k -> j -> Type) -> Constraint) (m :: k) (s :: k) (t :: j) (a :: k) (b :: j). (CategoryOf j, CategoryOf k, Ob m, Monoid m, (Ob a, Ob b) => c (ExOptic (FoldFl :: (k +-> k) -> (j +-> j) -> Constraint) a b)) => Optic c s t a b -> (a ~> m) -> s ~> m Source Github #

Fold through any optic that can act as a fold, in either encoding: run it at its witness pair (ExOptic FoldFl, via withLegs) and apply foldMapP.

traverseOf :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) p. (Distributive k, StrongDistributiveProfunctor p, Strong (ProdAction :: k -> (PROD k, k) -> Type) p, (Ob a, Ob b) => c (ExOptic (TravFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> p a b -> p s t Source Github #

Traverse: distribute any StrongDistributiveProfunctor -- not merely a Star f (the Hask van-Laarhoven shape) -- through any optic that is at least a Traversal. Works for an arbitrary profunctor carrier by handing it to travP, rather than relying on a per-carrier Prostrong w p bridge (which could only ever cover specific carrier heads).

The optic is accepted in any encoding: the constraint asks the optic's class to hold for the generic carrier ExOptic TravFl a b, which a Prostrong-flavored optic discharges via forall p q. w p q => Sub TravFl p q, a (%)-composite one conjunct at a time, and a profunctor-class one (PTraversalFull) through the carrier's by-generator instances.

monTraverseOf :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) p. (Distributive k, StrongDistributiveProfunctor p, (Ob a, Ob b) => c (ExOptic (MonTravFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> p a b -> p s t Source Github #

Like traverseOf, but for a MonoidalTraversal -- distributes any StrongDistributiveProfunctor with no product-strength requirement on the carrier. Every non-lens traversal (prism, Traversable functor, ...) is a monoidal traversal, so this accepts carriers like Writer w that are tensor-strong but not product-strong.

Accepts any encoding (cf. traverseOf): a PTraversal works directly, as does a (%)-composite.

powerGrateOf :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) r. (Monoidal k, MonoidalProfunctor r, (Ob a, Ob b) => c (ExOptic (PowerGrateFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> r a b -> r s t Source Github #

Distribute any MonoidalProfunctor through a power grate (or any stronger optic). At the hom (~>) this is over; at an applicative Star f the foci are combined through f.

Accepts any encoding (cf. traverseOf), including (%)-composites.

cotraverseOf :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) r. (CategoryOf k, Cotraversable r, (Ob a, Ob b) => c (ExOptic (CotravFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> r a b -> r s t Source Github #

Pass a Cotraversable carrier through a cotraversal (or any stronger optic, in any encoding, (%)-composites included).

kaleidoscopeOf :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) r. (CategoryOf k, Kaleidoscopic r, (Ob a, Ob b) => c (ExOptic (KaleidoFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> r a b -> r s t Source Github #

Act on a Kaleidoscopic carrier through a kaleidoscope (or any stronger optic, in any encoding, (%)-composites included). At Costar [] this is the literature's aggregation operator >-: from [a] -> b to [s] -> t.

zipWithOf :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k). (Monoidal k, Ob a, (Ob a, Ob b) => c (ExOptic (KaleidoFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> ((a ** a) ~> b) -> (s ** s) ~> t Source Github #

Zip two sources through a Kaleidoscope (or any stronger optic, a Grate in particular, in any encoding): combine the foci pairwise. This is kaleidoscopeOf at the carrier RepCostar (Pow 2), the costar of the binary tensor power -- a binary combination (a ** a) ~> b of foci, which the optic's applicative lifts by liftA2.

classifyOf :: forall {k} (m :: k +-> k) (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k). (OplaxMonoidalRep m, Comonoid a, (Ob a, Ob b) => c (ExOptic (AlgLensFl m) a b)) => Optic c s t a b -> ((m % s) ** b) ~> t Source Github #

Classify a monadic computation of s's through an AlgebraicLens (or any stronger optic, in any encoding), given a replacement focus b -- generalizing "set" to combine every s the computation might produce (via its residual's Algebra) rather than only ever seeing the last one. The focus a is discarded under the monad, hence must be a comonoid.

tracerOf :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) r. (Monoidal k, Costrong (Tensor :: k -> (k, k) -> Type) r, c (ExOptic (TracerFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> r a b -> r s t Source Github #

Distribute any Costrong profunctor through a tracer (or any stronger optic). At the hom this is over, computing the feedback loop through the residual.

Accepts any encoding (cf. traverseOf): a PTracer works directly, as does a (%)-composite.

withIso :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) r. (CategoryOf k, (Ob a, Ob b) => c (Yo a ('OP b))) => Optic c s t a b -> ((s ~> a) -> (b ~> t) -> r) -> r Source Github #

Eliminate any iso-flavored optic to its two legs, in either encoding -- including the profunctor-class-flavored PIso and reversed (re) isos.

withLens :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) r. (HasBinaryProducts k, (Ob a, Ob b) => c (ExOptic (LensFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> ((s ~> a) -> ((s && b) ~> t) -> r) -> r Source Github #

Eliminate any optic that is at least an iso and at most a lens to its two legs, in either encoding: run it at its witness pair (ExOptic LensFl, via withLegs) and read the legs off with getP and putP.

withMonLens :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) r. (SymMonoidal k, (Ob a, Ob b) => c (ExOptic (MonLensFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> (forall (m :: k). Ob m => ComonoidOn m -> (s ~> (m ** a)) -> ((m ** b) ~> t) -> r) -> r Source Github #

Eliminate any optic that is at least an iso and at most a monoidal lens to its two legs, recovering the existential residual m together with its comonoid structure: run it at its witness pair (ExOptic MonLensFl, via withLegs) and read the legs off with withMonLensP.

withPrism :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) r. (HasBinaryCoproducts k, (Ob a, Ob b) => c (ExOptic (PrismFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> ((b ~> t) -> (s ~> (t || a)) -> r) -> r Source Github #

Eliminate any optic that is at least an iso and at most a prism to its two legs, in either encoding: run it at its witness pair (ExOptic PrismFl, via withLegs) and read the legs off with matchingP and getP on the flipped pair (a prism's build leg is a getter read backwards).

withGrate :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) r. (Closed k, SymMonoidal k, (Ob a, Ob b) => c (ExOptic (GrateFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> ((forall (x :: k). Ob x => ((x ~~> a) ~> b) -> (x ~~> s) ~> t) -> r) -> r Source Github #

Eliminate any grate-flavored optic to its zipping function, in either encoding: run it at its witness pair (ExOptic GrateFl, via withLegs) and read the zipper off with zipWithP.

withGlass :: forall {k} (c :: (k -> k -> Type) -> Constraint) (s :: k) (t :: k) (a :: k) (b :: k) r. (CCC k, (Ob a, Ob b) => c (ExOptic (GlassFl :: (k +-> k) -> (k +-> k) -> Constraint) a b)) => Optic c s t a b -> (((s && ((s ~~> a) ~~> b)) ~> t) -> r) -> r Source Github #

Eliminate any glass-flavored optic (a lens, a grate, or a composite of both, in either encoding) to its single leg.

Operators and shorthands

(^.) :: forall (c :: (Type -> Type -> Type) -> Constraint) a b s t. c (ExOptic (GetterFl :: (Type +-> Type) -> (Type +-> Type) -> Constraint) a b) => s -> Optic c s t a b -> a infixl 8 Source Github #

View the focus of a concrete, Type-level optic.

(#) :: forall (c :: (Type -> Type -> Type) -> Constraint) a b s t. c (ExOptic (Flip (GetterFl :: (Type +-> Type) -> (Type +-> Type) -> Constraint)) a b) => Optic c s t a b -> b -> t infixr 8 Source Github #

Review through a concrete, Type-level optic.

(^?) :: forall s t a b (c :: (Type -> Type -> Type) -> Constraint). c (ExOptic (AffineFoldFl :: (Type +-> Type) -> (Type +-> Type) -> Constraint) a b) => s -> Optic c s t a b -> Maybe a infixl 8 Source Github #

Preview the focus of a concrete, Type-level optic (a getter that might not match).

(.?) :: forall f (c :: (Type -> Type -> Type) -> Constraint) s t a b. (Monad f, Functor f, c (ExOptic (AlgLensFl (Star f)) a b)) => Optic c s t a b -> b -> f s -> t infixl 8 Source Github #

classifyOf for a Haskell monad, curried: optic .? b $ fs.

set :: forall (c :: (Type -> Type -> Type) -> Constraint) a b s t. c (ExOptic (SetterFl :: (Type +-> Type) -> (Type +-> Type) -> Constraint) a b) => Optic c s t a b -> b -> s -> t Source Github #

Named version of (.~).

(%~) :: forall (c :: (Type -> Type -> Type) -> Constraint) a b s t. c (ExOptic (SetterFl :: (Type +-> Type) -> (Type +-> Type) -> Constraint) a b) => Optic c s t a b -> (a -> b) -> s -> t infixl 8 Source Github #

Apply a function through a concrete, Type-level Setter.

(.~) :: forall (c :: (Type -> Type -> Type) -> Constraint) a b s t. c (ExOptic (SetterFl :: (Type +-> Type) -> (Type +-> Type) -> Constraint) a b) => Optic c s t a b -> b -> s -> t infixl 8 Source Github #

Replace the focus/foci of a concrete, Type-level Setter with a constant value.

unfold :: forall {k} (c :: (OPPOSITE k -> OPPOSITE k -> Type) -> Constraint) (cm :: k) (s :: k) (t :: k) (a :: k) (b :: k). (Comonoid cm, Ob cm, forall (p :: OPPOSITE k +-> OPPOSITE k). c p => c (Op (UnOp p)), (Ob a, Ob b) => c (ExOptic (FoldFl :: (OPPOSITE k +-> OPPOSITE k) -> (OPPOSITE k +-> OPPOSITE k) -> Constraint) ('OP b) ('OP a))) => Optic (OpConstraint c) s t a b -> (cm ~> b) -> cm ~> t Source Github #

Unfold t from a Comonoid seed cm through the b-foci. It is foldMapOf run in OPPOSITE k, where Monoid becomes Comonoid and consumption becomes construction. (Inhabitable once the flavor's Prostrong transports through OP.)

Composing and converting optics

(%) :: forall {j} {k} (c1 :: (j +-> k) -> Constraint) (s :: k) (t :: j) (a :: k) (b :: j) (c2 :: (j +-> k) -> Constraint) (c :: k) (d :: j). Optic c1 s t a b -> Optic c2 a b c d -> Optic (c1 :&&: c2) s t c d infixl 9 Source Github #

Compose two optics, of any (possibly different) flavors or encodings. The composite's constraint is the conjunction :&&:, so the composite is automatically usable at exactly the meet of the two flavors' capabilities: a lens composed with a prism previews, folds, traverses and sets, but no longer views or reviews. Use convert to name the composite at a single flavor for storage, e.g. convert (l % p) :: AffineTraversal s t a b.

convert :: forall {j} {k} (c :: (k -> j -> Type) -> Constraint) (w :: FLAVOR j k) (s :: k) (t :: j) (a :: k) (b :: j). (CategoryOf j, CategoryOf k, Flavor w, (Ob a, Ob b) => c (ExOptic w a b)) => Optic c s t a b -> Optic (Prostrong w) s t a b Source Github #

Convert an optic to a chosen flavor w, by running it at its existential encoding ExOptic w a b and wrapping the resulting witness pair back around the carrier: this works for any input encoding. A Prostrong-flavored optic converts along the subtyping lattice (via the bridge instance of ExOptic; an invalid conversion fails with Could not deduce (w p q) for the missing superclass), a :&&:-composite converts when both conjuncts do, and a profunctor-class-flavored optic converts when ExOptic w a b has an instance of its class -- which it does for every class whose generating witnesses w contains (cf. fromPIso, fromPTraversal, fromPTracer).

Consumers accept any sufficiently strong optic directly, so this is rarely needed to use an optic; but constructors and % return their exact type monomorphically, so it is the way to store an optic at a weaker type, e.g. convert (lens f g) :: Traversal' s a.

class (Monad m, Ob a) => Algebra (m :: k +-> k) (a :: k) where Source Github #

An Eilenberg-Moore algebra for the monad m -- a representable Promonad on k, acting as the functor m % - (Proarrow.Promonad): a structure map m % a ~> a, coherent with the monad's unit and multiplication. The free algebras m % s are the ones an algebraic lens is built from (algebraicLens).

There are deliberately no instances for the unit or for products of algebras, and there cannot be: Unit and (**) are type families, which may not head an instance. That is why withAlgP passes the structure map as a value -- the composition instance pairs two algebras with unparRep and the identity witness supplies the unit one with unpar0Rep, neither needing an Algebra instance. A witness pair whose residual is the unit is the identity optic up to the unitors, so nothing is lost.

Methods

algebra :: (m % a) ~> a Source Github #

Instances

Instances details
(Monad (Star m), Ob (m a), Ob a) => Algebra (Star m :: k -> k -> Type) (m a :: k) Source Github #

The free algebras of a monad m, wrapped as the representable promonad Star m.

Instance details

Defined in Proarrow.Optic.Action

Methods

algebra :: (Star m % m a) ~> m a Source Github #

toPTraversal :: forall {k} (s :: k) (t :: k) (a :: k) (b :: k). Distributive k => MonoidalTraversal s t a b -> PTraversal s t a b Source Github #

Half of the equivalence between the two traversal encodings: eliminate the existential witnesses with travP at the caller's profunctor.

toPTraversalFull :: forall {k} (s :: k) (t :: k) (a :: k) (b :: k). Distributive k => Traversal s t a b -> PTraversalFull s t a b Source Github #

Eliminate a Traversal to its profunctor-class form (the analog of toPTraversal): run travP at the caller's profunctor.

fromPTraversal :: forall {k} (s :: k) (t :: k) (a :: k) (b :: k). (Distributive k, CopyDiscard k, SymMonoidal k) => PTraversal s t a b -> MonoidalTraversal s t a b Source Github #

The other half of the equivalence between the encodings: instantiate the profunctor-class-flavored traversal at the generic carrier ExOptic MonTravFl a b, which is an SDP by the by-generator instances above. Because its tensor strength comes from the tensor-action witness Rep (ActionAt Tensor _) (not a product lens), this needs no Cartesian (tensor = product), only CopyDiscard (a discard a ~> Unit for the residual) -- which is exactly what the coproduct-prism witness already demanded -- enabling e.g. the biproduct categories Mat and FinRel (but not LINEAR, which cannot discard). A Traversal is recovered for free wherever one is needed, since MonTravFl@ is a subflavor of TravFl.