Constructors
Optical (arr a b -> arr s t)
:: a typeCtrl KGHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05
Modulelinear-base-0.4.0Haskell2010
This module provides linear optics.
Documentation for specific optics (lenses, prisms, traversals and isomorphisms) are provided in their respective modules.
Here we just provide an overview.
Some familiarity with optics is needed to understand linear optics. Please go through the (hopefully friendly!) background material section if you are unfamiliar with lenses, prisms, traversals or isomorphisms.
If you don't know anything about optics, we suggest looking at the
resources below and playing with the lens package.
The wiki of the lens package
that contains some nice examples
Optics can be conceptualized as a first class object with which you can view and map functions over sub-structure(s) within a larger structure.
Linear optics are optics where the "viewing" and "mapping" are done with linear functions (and any corresponding structures hold values linearly, i.e., with constructors that use linear arrows).
In types: a (linear) optic of type Optic s t a b is a way of viewing the
sub-structure(s) of type a in the structure of type s and mapping a
function from an a to a b on those sub-structures in s which change an
s to a t. The non-polymorphic version of the optic is specialized
to the types Optic s s a a and is usually defined with a tick mark,
e.g., the non-polymorphic Lens is Lens'.
There are four basic optics: traversals, lenses, prisms and isomorphisms.
\texttt{Traversal}
\Huge \nearrow ~~~~~ \nwarrow
\texttt{Lens}\hspace{6em}\texttt{Prism}
\Huge \nwarrow ~~~~~ \nearrow
\texttt{Iso}
In the diagram above, the arrows X --> Y mean any of the following
equivalent things:
X is a specialization of Y
X is a strict subset of Y
You can (basically) implement f :: X -> Y with f = id
but you can't implement f :: Y -> X.
The types of linear optics are generalizations of the standard optic
types from the lens package.
These are the standard optic types:
type Traversal s t a b =
forall f. Applicative f => (a -> f b) -> s -> f t
type Lens s t a b =
forall f. Functor f => (a -> f b) -> (s -> f t)
type Prism s t a b =
forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t)
type Iso s t a b =
forall p f. (Profunctor p, Functor f) => a `p` (f b) -> s `p` (f t)These are (basically) the linear optic types:
type Traversal a b s t =
forall arr. Wandering arr => (a `arr` b) -> (s `arr` t)
type Lens a b s t =
forall arr. Strong (,) () arr => (a `arr` b) -> (s `arr` t)
type Prism a b s t =
forall arr. Strong Either Void arr => (a `arr` b) -> (s `arr` t)
type Iso a b s t =
forall arr. Profunctor arr => (a `arr` b) -> (s `arr` t)Below is a table that lists the instances of the typeclasses which generalize the standard optics.
Note that Kleisli arrows basically defined like so:
type Kleisli f a b = a %1-> f bNote: We abbreviate Control for Control.Functor.Linear.
Profunctor | Strong (,) () | Strong Either Void | Wandering | |
|---|---|---|---|---|
| X | X | X | |
| X | X | X | |
(Prelude)
| X (4) | X |
|
|
(Data.Functor)
| X |
|
|
|
(Prelude)
| X | X | X (3) |
|
(Control)
| X | X (2) |
|
|
(Control)
| X | X | X | X (1) |
Essentially:
The instance marked (1) implies that the linear traversal definition includes the standard one
The instance marked by (2) implies that the linear lens definition includes the standard one
The instance marked by (3) implies that the linear prism definition includes the standard one
The instance marked by (4) implies that the linear iso definition includes the standard one
Optical (arr a b -> arr s t)module Control.Optics.Linear.Iso
module Control.Optics.Linear.Lens
module Control.Optics.Linear.Prism