tur/lens
first-class functional lenses (getter/setter optics).
A Lens S A focuses on a part A inside a whole S: it pairs a getter S -> A with a setter A -> S -> S. view/set/over read, replace, and transform the focused part; lens-compose chains two lenses so an optic can reach nested structure.
## Encoding
This module uses the **profunctor-by-record** encoding -- a Lens is a concrete record of two functions -- rather than the van Laarhoven form type Lens s a = forall f. Functor f => (a -> f a) -> (s -> f s). The van Laarhoven encoding is inexpressible on Turmeric's type-erased HRT today: the lens body must dispatch fmap on the caller-chosen functor f (Const for view, Identity for set/over), which needs runtime typeclass-dictionary passing through the poly carrier -- deferred (mode B of docs/archive/history/constrained-hkt-forall-plan.md). The record encoding needs none of that and composes fine via the explicit lens-compose combinator; the one thing it gives up is composing optics with ordinary function composition (compose), which the van Laarhoven form allows.
## Value semantics
A Lens is :copy so it can be viewed/set/over'd repeatedly. The whole S a lens focuses is typically a :copy (and, for a record you rebuild in the setter, :heap) struct so it too can be reused across calls.
Since: constrained-hkt-forall slice 4
Lens
(defstruct Lens :copy [S A] (lget (fn [S] A)) (lput (fn [A S] S)))
lens
(lens [S A])
build a Lens from a getter and a setter.
| get | reads the focused A out of the whole S | |
| put | returns a new S with the focused A replaced |
A Lens S A pairing get and put.
(lens (fn [p : Point] : int (.x p))
(fn [nx : int p : Point] : Point
(make-struct Point :x nx :y (.y p))))
Since: constrained-hkt-forall slice 4
view
(view [S A])
read the focused A out of the whole S.
| l | the lens | |
| s | the whole value |
The focused part A.
(view point-x p) ; => (.x p)
Since: constrained-hkt-forall slice 4
set
(set [S A])
replace the focused A, returning the updated S.
| l | the lens | |
| a | the new focused value | |
| s | the whole value |
A new S with the focus replaced by a.
(set point-x 42 p) ; => p with x = 42
Since: constrained-hkt-forall slice 4
over
(over [S A])
apply a function to the focused A, returning the updated S.
| l | the lens | |
| f | transforms the focused value | |
| s | the whole value |
A new S with the focus mapped through f.
(over point-x (fn [v : int] : int (* v 10)) p) ; => p with x *= 10
Since: constrained-hkt-forall slice 4