Many types of optics have a van Laarhoven representation.
For example, a Lens
of type Lens s t a b
can be represented as:
Functor f => (a -> f b) -> s -> f t
Similarly a Traversal
, can be represented in a similar way, swapping the Functor
constraint for Applicative
:
Applicative f => (a -> f b) -> s -> f t
Several optics frameworks, such as Monocle and Arrow define a type called Optional
.
In Monocle's Optics heirarchy Optional
fits between Lens
and Traversal
As I understand it: If a Traversal
is like a Lens
that may have zero to many targets, then an Optional
is like a Lens
that may have zero to one targets.
In Monocle, Optional
is defined as a pair of functions:
getOrModify :: s -> Either t a
set :: (b, s) -> t
Comments in the Monocle source code suggest that it's also possible to represent an Optional
"as a weaker PLens
and weaker PPrism
"
Is it possible to represent an Optional
as a van Laarhoven function?
There would be a way to represent it if the Functor/Applicative/Monad hierarchy were more fine-grained. In particular:
class Functor f => Pointed f where
pure :: a -> f a
type Optional s t a b = forall f. Pointed f => (a -> f b) -> s -> f t
Note that the type would probably be named Affine
in the lens library if that was neatly in the class hierarchy.