import * as fun from "https://deno.land/x/fun@v2.0.0/optic.ts";
Optics are a collection of combinators for focusing on specific parts of data within an existing structure. The core operations are view, review, and modify. Optics in the fun library are based on the concept of Kliesli optics as outlined here.
Their uses include (but are not limited to):
- Accessing deeply nested data
- Mapping related but distinct types without loss of fidelity
- Immutably modifying large data structures
At its core, instead of separating the view method into view, preview, and toList of, as is done in many languages and libraries. This implementation uses a single view method that operates as a Kliesli arrow (a -> mb) where the m in this case is limited to the Identity, Option, and Array monads, which can be composed using Natural transformations and flatMap.
In addition to view, there are also implementations of review and modify, which also have composition functions.. but the research for composition is not yet complete for review.
In any case, this implementation of optics is distinct from Laarhoven lenses and profunctor optics, and is much more compact and performant in typescript than those implementations.
Variables
A runtime tag and type that indicates an Optic has a view function of the form
| |
A preconstructed traversal that focuses the values of a ReadonlyArray. | |
A preconstructed composed lens that focuses on the First value of a Pair. | |
A runtime tag and type that indicates an Optic has a view function of the form
| |
v left | A preconstructed composed prism that focuses on the Left value of an Either. |
A runtime tag and type that indicates an Optic has a view function of the form
| |
v nil | A preconstructed filter that focuses on the the non-null and non-undefined value of A | null | undefined. |
A preconstructed traversal that focuses the values of a ReadonlyRecord. | |
A preconstructed composed prism that focuses on the Right value of an Either. | |
A preconstructed composed lens that focuses on the Second value of a Pair. | |
v set | A preconstructed traversal that focuses the values of a ReadonlySet. |
v some | A preconstructed composed prism that focuses on the Some value of an Option. |
v tree | A preconstructed traversal that focuses the values of a Tree. |
Functions
Given a Viewer<U, S, A> and an optic tag V, this function produces a view function that can be used in a Viewer<V, S, A>. However, not all casts are valid. The following are the only supported casts, by their optic tag: | |
Construct an AffineFold<S, A> from view and modify functions. | |
A composible combinator that focuses on a key in a readonly record. The difference between atKey and key is that the key can be removed from the record by the modify function if the modify function returns None. | |
Construct a composable combinator from an instance of Comparable and a key of a map. The combinator can then be composed with an existing optic to access or remove the value in the map. | |
Given a Combinable and a function A -> I, collect all values A focused on by an optic into a single value I. | |
Compose two optics, aligning their tag and building the composition using natural transformations and monadic chaining for the view function and using direct composition for the modify function. | |
Compose two reviewer functions, allowing one to create nested Reviewer structures. | |
A composible combinator that can filter or refine the focused value of an existing optic. Care should be taken with this operator as it apples to the modify function as well as the view function. That is to say that if the refinement or predicate returns false for the focused value then that value will not be modified. See the example for clarification. | |
f fold | Construct a Fold<S, A> from view and modify functions. |
Construct a Prism<S, A> from a Refinement<S, A>. | |
f id | Construct an Iso<A, A> from a type level argument. This is the entrypoint to almost all optics as it allows one to start with a type and compose other optics from there. |
f imap | An invariant map over an Optic. If a type can be represented isomorphically by another type, one can imap to go back and forth. |
A composible combinator that focuses on a value in an array at the given index. | |
f iso | Construct an Iso<S, A> from view and review functions, with an optional modify function if it is different from |
f key | A composible combinator that focuses on a key in a readonly record. |
f lens | Construct a Lens<S, A> from view and modify functions. |
Construct a Modifier<S, A. from a modify function. | |
A pipeable modify function that applies a modification function to a Modifier<S, A> modify function. It will return a function S -> S that applies the modify function according to the type of optic. Note: All Optics are Modifiers. | |
Construct an Optic<U, S, A> & Reviewer<S, A> from a tag as well as view, modify, and reivew functions. | |
Construct a Prism<S, A> from view and review functions, with an optional modify function that will be defaulted if not provided. | |
f prop | A composable combinator that focuses on a property P of a struct. |
A composible combinator that focuses on a list of properties of a struct. | |
Construct a Refold<S, A> from view, review, and modify functions. | |
A pipeable replace function, that uses the modify function of an Optic to replace an existing value over the structure S. | |
A pipeable review function that applies a value A to the the review function of a Reviewer<S, A>. It returns a value S. | |
Construct a Reviewer<S, A> from a review function. | |
Construct a composable optic from a Traversable instance for a Kind T. This will fold the values wrapped in the Kind T into a single Array when viewed. | |
f view | A pipeable view function that applies a value S to a Viewer<S, A>. It will return either a raw value, an option, or a readonlyarray based on the tag of the Viewer. Note: All Optics are Viewers. |
Construct a Viewer<T, S, A> from a tag T and a view function that matches said tag. This is a raw constructor and is generally only useful if there is a case where a structure can be lensed into but not reconstructed or traversed. However, this is the core composable structure of optics, as they are primarily meant as a way to retrieve data from an existing structure. | |
f wrap | Construct a Lens Viewer from a raw value A. The view function of this viewer operatates like constant(a). |
Interfaces
The Modifier<S, A> type implements the modify function
| |
An Optic<T, S, A> is defined as a Viewer<T, S, A> combined with a Modifier<S, A>. This is the root type for the specific types of Optics defined below. | |
The Reviewer<S, A. type implements the review function | |
A Viewer<T, S, A> implements a view function |
Type Aliases
AffineFold<S, A> is an alias of Optic<AffineTag, S, A>. This means the view
function of an AffineFold returns an Option, | |
T Fold | Fold<S, A> is an alias of Optic<FoldTag, S, A>. This means that the view
function of a Fold returns a ReadonlyArray, |
T Iso | Iso<S, A> is an alias of Lens<S, A> & Reviewer<S, A>. This means that an Iso operates exactly like a Lens with the added ability to go back from A to S. |
T Lens | Lens<S, A> is an alias of Optic<LensTag, S, A>. This means that the view
function of a Lens returns a pure A value. |
Prism<S, A> is an alias of AffineFold<S, A> & Reviewer<S, A>. This means that a Prism operates exactly like an AffineFold with the added ability to reconstruct an S from an A. Examples of this are reconstructing an Option from a number, or reconstructing Either<string, number> from a string or a number. | |
Refold<S, A> is an alias of Fold<S, A> & Reviewer<S, A>. This means that a Refold operates exactly like a Fold with the added ability to reconstruct an S from a single value A. Examples of this are reconstructing an Array from a value A, or reconstructing a Tree from a value A. | |
T Tag | A type union of the supported view tags for a Viewer |