LokoTypically one either refers to the library primitives through the Loko module name or, as done in this documentation, uses an abbreviation such as
module L = Lokoto keep code more succinct.
Loko uses ordinary function composition to compose optics and for convenience, the Infix submodule
open L.Infixprovides the % operator for that purpose.
NOTE: The abstractions in this section serve auxiliary roles for the definition of optics.
module Infix : sig ... endInfix operators for convenient use of optics.
module Iterator : sig ... endImperative iterator.
module Builder : sig ... endImperative builder.
The pipe type constructor hides most of the implementation details of optics and basically represents a function that takes values of type 'S as input and produces values of type 'T as output.
Optics are functions over pipes and are composable with normal function composition.
type ('S, 'F, 'G, 'T) optic := ('S, 'F, 'G, 'T) tErased type alias for optic.
val iso : ('S -> 'F) -> ('G -> 'T) -> ('S, 'F, 'G, 'T) tDefines a new invertible isomorphism from a pair of conversion functions.
# let plus n = L.iso (( + ) n) (Fun.flip ( - ) n)
val plus : int -> (int, int, int, int) L.t = <fun>
# L.view (plus 1) 2
- : int = 3
# L.review (plus 2) 3
- : int = 1
# L.view (L.re (plus 2)) 3
- : int = 1val lens : ('S -> 'F) -> ('G -> 'S -> 'T) -> ('S, 'F, 'G, 'T) tDefines a new lens from a getter and setter.
val partial_lens :
('S -> 'F option) ->
('G -> 'S -> 'T) ->
('S -> 'T) ->
('S, 'F, 'G, 'T) tDefines a new partial lens from a getter, setter, and remover.
val getter : ('S -> 'F) -> ('S, 'F, 'G, 'S) tDefines a new getter.
fold_lens fold traversal defines a lens out of a suitable fold and a traversal.
val prism :
('S -> ('T, 'F) Stdlib.Either.t) ->
('G -> 'T) ->
('S, 'F, 'G, 'T) tDefines a new invertible prism from a constructor-destructor pair.
# let ends_with suffix =
L.prism
(fun string ->
if Filename.check_suffix string suffix then
Right (Filename.chop_suffix string suffix)
else Left string)
(fun prefix -> prefix ^ suffix)
val ends_with : string -> (string, string, string, string) L.t = <fun>
# L.view (ends_with ".ml") "Loko.ml"
- : string = "Loko"
# L.set (ends_with ".ml") "Loco" "Loko.ml"
- : string = "Loco.ml"
# L.can_view (ends_with ".ml") "Loko.mli"
- : bool = false
# L.set (ends_with ".ml") "Loco" "Loko.mli"
- : string = "Loko.mli"val traversal : ('S, 'F) Iterator.t -> ('G, 'T) Builder.t -> ('S, 'F, 'G, 'T) tDefines a new traversal from an iterator-builder pair.
Defines a new traversal over the elements of a 2-tuple.
val branch'3 :
('F1, 'F, 'G, 'G1) t ->
('F2, 'F, 'G, 'G2) t ->
('F3, 'F, 'G, 'G3) t ->
('F1 * 'F2 * 'F3, 'F, 'G, 'G1 * 'G2 * 'G3) tDefines a new traversal over the elements of a 3-tuple.
val branch'4 :
('F1, 'F, 'G, 'G1) t ->
('F2, 'F, 'G, 'G2) t ->
('F3, 'F, 'G, 'G3) t ->
('F4, 'F, 'G, 'G4) t ->
('F1 * 'F2 * 'F3 * 'F4, 'F, 'G, 'G1 * 'G2 * 'G3 * 'G4) tDefines a new traversal over the elements of a 4-tuple.
val can_view : ('S, 'F, 'G, 'T) t -> 'S -> boolDetermines whether the optic has a focus on the data.
val view : ('S, 'F, 'G, 'T) t -> 'S -> 'FExtracts the first focus of the optic on the data. Raises when there is no focus.
val view_opt : ('S, 'F, 'G, 'T) t -> 'S -> 'F optionAttempts to extract the first focus of the optic on the data.
val can_review : ('S, 'F, 'G, 'T) t -> 'G -> boolDetermines whether the optic has an inverse focus on the data.
val review : ('S, 'F, 'G, 'T) t -> 'G -> 'TViews through isomorphism in inverse direction. Raises when the optic is not reversible or doesn't have inverse focus on the data.
val review_opt : ('S, 'F, 'G, 'T) t -> 'G -> 'T optionAttempts to extract the inverse focus of the optic on the data. WARNING: This will raise when the optic is not reversible.
val can_over : ('S, 'F, 'G, 'T) t -> ('F -> 'G) -> 'S -> boolDetermines whether the focuses of the optic on the data can be updated.
val over : ('S, 'F, 'G, 'T) t -> ('F -> 'G) -> 'S -> 'TUpdates the focuses of the optic on the data. Raises when cannot.
val over_default : ('S, 'F, 'G, 'S) t -> ('F -> 'G) -> 'S -> 'SUpdates the focuses of the optic on the data. Returns input when cannot.
val over_opt : ('S, 'F, 'G, 'T) t -> ('F -> 'G) -> 'S -> 'T optionAttempts to update the focuses of the optic on the data.
val can_set : ('S, 'F, 'G, 'T) t -> 'G -> 'S -> boolDetermines whether the focuses of the optic on the data can be set.
val set : ('S, 'F, 'G, 'T) t -> 'G -> 'S -> 'TSets the focuses of the optic on the data. Raises when cannot.
val set_default : ('S, 'F, 'G, 'S) t -> 'G -> 'S -> 'SSets the focuses of the optic on the data. Returns input when cannot.
val set_opt : ('S, 'F, 'G, 'T) t -> 'G -> 'S -> 'T optionAttempts to set the focuses of the optic on the data.
val can_remove : ('S, 'F, 'G, 'T) t -> 'S -> boolDetermines whether the focuses of the optic on the data can be removed.
val remove : ('S, 'F, 'G, 'T) t -> 'S -> 'TRemoves the focuses of the optic on the data. Raises when cannot.
val remove_default : ('S, 'F, 'G, 'S) t -> 'S -> 'SRemoves the focuses of the optic on the data. Returns input when cannot.
val remove_opt : ('S, 'F, 'G, 'T) t -> 'S -> 'T optionAttempts to remove the focuses of the optic on the data.
val disperse : ('S, 'F, 'G, 'T) t -> 'G array -> 'S -> 'TInjects array elements to the focuses or removes them. Raises when cannot.
val disperse_keep : ('S, 'F, 'F, 'T) t -> 'F array -> 'S -> 'TInjects array elements to the focuses or keeps them. Raises when cannot.
Converts an optic to a lens focusing on an array of the focuses.
Converts an optic to a lens focusing on an array of the focuses.
val transform : ('S, 'F, 'F, 'T) t -> 'S -> 'Ttransform optic data is equivalent to over optic Fun.id data.
val remove_op : ('S, 'F, 'G, 'T) tSignal removal of current focus.
val over_op : ('S -> 'T) -> ('S, 'F, 'G, 'T) tUpdate focus with given function.
val set_op : 'T -> ('S, 'F, 'G, 'T) tUpdate focus with given value.
A non-isomorphism computed from the focus.
A choice between two non-isomorphisms depending on the focus.
or_else secondary primary acts like the primary when it can view and otherwise like secondary.
A lens focusing on a pair of focuses. Given optics should be separable lenses.
op_1 |> and_then op_2 first performs with op_1 and then op_2.
# L.transform (L.over_op (( + ) 2) |> L.and_then (L.over_op (( * ) 3))) 1
- : int = 9
# L.transform
((L.fst |> L.and_then L.snd) % L.over_op Int.to_string)
(1, 2)
- : string * string = ("1", "2")The cond_of, case, and otherwise combinators provide an alternative syntax for conditional optics. In general,
cond_of traversal
@@ case predicate_1 optic_1
@@ case predicate_2 optic_2
...
@@ case predicate_n optic_n
@@ otherwise opticis equivalent to
if_else (exists predicate_1 traversal) t_1
@@ if_else (exists predicate_2 traversal) optic_2
...
@@ if_else (exists predicate_n traversal) optic_n
@@ opticcond_of traversal starts a conditional optic definition where the following cases use the traversal to extract targets for their predicates.
val case :
('C -> bool) ->
('S, 'F, 'G, 'T) t ->
(('S, 'C, 'C, 'U) t -> ('S, 'F, 'G, 'T) t) ->
('S, 'C, 'C, 'U) t ->
('S, 'F, 'G, 'T) tcase predicate optic continues a conditional optic definition with given predicate and consequent optic.
otherwise optic ends a conditional optic definition and provides the default optic to use when none of the cases match the focus.
val zero : ('S, 'F, 'G, 'S) tAn optic that never has a focus.
val removed_if : ('G -> bool) -> ('F, 'F, 'G, 'G) tAn identity like optic that signals removal when written value matches predicate.
val as_removed : 'G -> ('F, 'F, 'G, 'G) tA prism like optic that signals removal when written with equal value.
val removed_as : 'G -> ('F, 'F, 'G, 'G) tA prism like optic that maps a removed focus to given value when written.
val removed_as_none : ('F, 'F, 'G, 'G option) tA prism like optic that maps a removed focus to None when written.
val none_as_removed : ('F, 'F, 'G option, 'G) tA prism like optic that maps None to a removed focus when written.
val removed_option : ('F option, 'F, 'G, 'G) tAn optic that peels away Some on read and removes None on write.
val accept : ('F -> bool) -> ('F, 'F, 'F, 'F) tA prism with a focus only when it passes the given predicate.
# L.remove
(L.List.elems % L.accept (fun x -> 4 < x))
[ 5; 3; 1; 6; 4; 1 ]
- : int list = [3; 1; 4; 1]val reject : ('F -> bool) -> ('F, 'F, 'F, 'F) tA prism with a focus except when it passes the given predicate.
# L.remove
(L.List.elems % L.reject (fun x -> x < 5))
[ 5; 3; 1; 6; 4; 1 ]
- : int list = [3; 1; 4; 1]val id : ('S, 'S, 'T, 'T) tThe identity isomorphism.
Inverts the given optic. Raises when not given an invertible optic.
val reread : ('S -> 'F) -> ('S, 'F, 'T, 'T) tAn isomorphism that maps the focus with given function when read.
val rewrite : ('G -> 'T) -> ('S, 'S, 'G, 'T) tAn isomorphism that maps the focus with given function when written.
val normalize : ('S -> 'F) -> ('S, 'F, 'S, 'F) tAn isomorphism that maps the focus with given function in both ways.
val subset : ('S -> bool) -> ('S, 'S option, 'T, 'T) tAn isomorphism between values and values that pass the predicate.
val to_default : 'F -> ('F option, 'F, 'G, 'G) tAn isomorphism that maps None to the given default value when read.
val of_default : 'G -> ('F, 'F, 'G, 'G option) tAn isomorphism that maps the given default value to None when written.
val default : 'F -> ('F option, 'F, 'F, 'F option) tAn isomorphism that maps None to the given default value when read and maps the default value to None when written.
val is_or : falsy:'F -> truthy:'F -> ('F, bool, bool, 'F) tAn isomorphism between given values and booleans. Only truthy maps to true when read.
val apply_at :
('S, 'Si, 'Fi, 'F) t ->
('G, 'Gi, 'Ti, 'T) t ->
('Si, 'Fi, 'Gi, 'Ti) t ->
('S, 'F, 'G, 'T) tTODO
val before : ('S -> unit) -> ('S, 'S, 'T, 'T) tAn identity like optic that performs a given side-effect when viewed.
val after : ?on_removed:(unit -> unit) -> ('T -> unit) -> ('S, 'S, 'T, 'T) tAn identity like optic that performs given side-effects when written.
val fold : 'R -> ('R -> 'F -> 'R) -> ('S, 'F, 'G, 'T) t -> 'S -> 'RFolds over the focuses of the optic on the data.
# L.fold 0 ( + ) L.List.elems [ 3; 1; 4 ]
- : int = 8val iter : ('S, 'F, 'G, 'T) t -> ('F -> unit) -> 'S -> unitIterates over the focuses of the optic on the data.
val count : ('S, 'F, 'G, 'T) t -> 'S -> intCounts the number of focuses the optic has on the data.
Collects values of the focuses of the optic on the data with the given builder.
val collect : ('S, 'F, 'G, 'T) t -> 'S -> 'F listExtracts a list of all the focuses of the optic on the data.
val exists : ('F -> bool) -> ('S, 'F, 'F, 'T) t -> 'S -> boolDetermines whether any focus of the optic on the data satisfy the predicate.
val forall : ('F -> bool) -> ('S, 'F, 'F, 'T) t -> 'S -> boolDetermines whether all focuces of the optic on the data satisfy the predicate.
val disjunction : ('S, bool, bool, 'T) t -> 'S -> booldisjunction optic data is equivalent to exists Fun.id optic data.
val conjunction : ('S, bool, bool, 'T) t -> 'S -> boolconjunction optic data is equivalent to forall Fun.id optic data.
val concat : string -> ('S, string, 'G, 'T) t -> 'S -> stringConcatenates all of the focuses of the optic on the data with given separator.
val fst : ('L1 * 'R, 'L1, 'L2, 'L2 * 'R) tA lens focusing on the first element of a pair.
val snd : ('L * 'R1, 'R1, 'R2, 'L * 'R2) tA lens focusing on the second element of a pair.
val iso_pair :
('SL, 'FL, 'GL, 'TL) t ->
('SR, 'FR, 'GR, 'TR) t ->
('SL * 'SR, 'FL * 'FR, 'GL * 'GR, 'TL * 'TR) tAn isomorphism between pairs.
val elem_1_of_2 : ('F * 'X2, 'F, 'G, 'G * 'X2) tval elem_2_of_2 : ('X1 * 'F, 'F, 'G, 'X1 * 'G) tval elem_1_of_3 : ('F * 'X2 * 'X3, 'F, 'G, 'G * 'X2 * 'X3) tval elem_2_of_3 : ('X1 * 'F * 'X3, 'F, 'G, 'X1 * 'G * 'X3) tval elem_3_of_3 : ('X1 * 'X2 * 'F, 'F, 'G, 'X1 * 'X2 * 'G) tval elem_1_of_4 : ('F * 'X2 * 'X3 * 'X4, 'F, 'G, 'G * 'X2 * 'X3 * 'X4) tval elem_2_of_4 : ('X1 * 'F * 'X3 * 'X4, 'F, 'G, 'X1 * 'G * 'X3 * 'X4) tval elem_3_of_4 : ('X1 * 'X2 * 'F * 'X4, 'F, 'G, 'X1 * 'X2 * 'G * 'X4) tval elem_4_of_4 : ('X1 * 'X2 * 'X3 * 'F, 'F, 'G, 'X1 * 'X2 * 'X3 * 'G) tval truncate : (float, int, int, float) tAn isomorphism between integers and floats.
module Array : sig ... endmodule Either : sig ... endmodule List : sig ... endmodule Map : sig ... endmodule Option : sig ... endmodule Result : sig ... endmodule String : sig ... end