Loko
Typically 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 = Loko
to keep code more succinct.
Loko
uses ordinary function composition to compose optics and for convenience, the Infix
submodule
open L.Infix
provides the %
operator for that purpose.
NOTE: The abstractions in this section serve auxiliary roles for the definition of optics.
module Infix : sig ... end
Infix operators for convenient use of optics.
module Iterator : sig ... end
Imperative iterator.
module Builder : sig ... end
Imperative 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 pipe
s and are composable with normal function composition.
type ('S, 'F, 'G, 'T) optic := ('S, 'F, 'G, 'T) t
Erased type alias for optic.
val iso : ('S -> 'F) -> ('G -> 'T) -> ('S, 'F, 'G, 'T) t
Defines 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 = 1
val lens : ('S -> 'F) -> ('G -> 'S -> 'T) -> ('S, 'F, 'G, 'T) t
Defines a new lens from a getter and setter.
val partial_lens :
('S -> 'F option) ->
('G -> 'S -> 'T) ->
('S -> 'T) ->
('S, 'F, 'G, 'T) t
Defines a new partial lens from a getter, setter, and remover.
val getter : ('S -> 'F) -> ('S, 'F, 'G, 'S) t
Defines 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) t
Defines 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) t
Defines 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) t
Defines 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) t
Defines a new traversal over the elements of a 4-tuple.
val can_view : ('S, 'F, 'G, 'T) t -> 'S -> bool
Determines whether the optic has a focus on the data.
val view : ('S, 'F, 'G, 'T) t -> 'S -> 'F
Extracts 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 option
Attempts to extract the first focus of the optic on the data.
val can_review : ('S, 'F, 'G, 'T) t -> 'G -> bool
Determines whether the optic has an inverse focus on the data.
val review : ('S, 'F, 'G, 'T) t -> 'G -> 'T
Views 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 option
Attempts 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 -> bool
Determines whether the focuses of the optic on the data can be updated.
val over : ('S, 'F, 'G, 'T) t -> ('F -> 'G) -> 'S -> 'T
Updates the focuses of the optic on the data. Raises when cannot.
val over_default : ('S, 'F, 'G, 'S) t -> ('F -> 'G) -> 'S -> 'S
Updates the focuses of the optic on the data. Returns input when cannot.
val over_opt : ('S, 'F, 'G, 'T) t -> ('F -> 'G) -> 'S -> 'T option
Attempts to update the focuses of the optic on the data.
val can_set : ('S, 'F, 'G, 'T) t -> 'G -> 'S -> bool
Determines whether the focuses of the optic on the data can be set.
val set : ('S, 'F, 'G, 'T) t -> 'G -> 'S -> 'T
Sets the focuses of the optic on the data. Raises when cannot.
val set_default : ('S, 'F, 'G, 'S) t -> 'G -> 'S -> 'S
Sets the focuses of the optic on the data. Returns input when cannot.
val set_opt : ('S, 'F, 'G, 'T) t -> 'G -> 'S -> 'T option
Attempts to set the focuses of the optic on the data.
val can_remove : ('S, 'F, 'G, 'T) t -> 'S -> bool
Determines whether the focuses of the optic on the data can be removed.
val remove : ('S, 'F, 'G, 'T) t -> 'S -> 'T
Removes the focuses of the optic on the data. Raises when cannot.
val remove_default : ('S, 'F, 'G, 'S) t -> 'S -> 'S
Removes the focuses of the optic on the data. Returns input when cannot.
val remove_opt : ('S, 'F, 'G, 'T) t -> 'S -> 'T option
Attempts to remove the focuses of the optic on the data.
val disperse : ('S, 'F, 'G, 'T) t -> 'G array -> 'S -> 'T
Injects array elements to the focuses or removes them. Raises when cannot.
val disperse_keep : ('S, 'F, 'F, 'T) t -> 'F array -> 'S -> 'T
Injects 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 -> 'T
transform optic data
is equivalent to over optic Fun.id data
.
val remove_op : ('S, 'F, 'G, 'T) t
Signal removal of current focus.
val over_op : ('S -> 'T) -> ('S, 'F, 'G, 'T) t
Update focus with given function.
val set_op : 'T -> ('S, 'F, 'G, 'T) t
Update 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 optic
is 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
@@ optic
cond_of traversal
starts a conditional optic definition where the following case
s 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) t
case 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 case
s match the focus.
val zero : ('S, 'F, 'G, 'S) t
An optic that never has a focus.
val removed_if : ('G -> bool) -> ('F, 'F, 'G, 'G) t
An identity like optic that signals removal when written value matches predicate.
val as_removed : 'G -> ('F, 'F, 'G, 'G) t
A prism like optic that signals removal when written with equal value.
val removed_as : 'G -> ('F, 'F, 'G, 'G) t
A prism like optic that maps a removed focus to given value when written.
val removed_as_none : ('F, 'F, 'G, 'G option) t
A prism like optic that maps a removed focus to None
when written.
val none_as_removed : ('F, 'F, 'G option, 'G) t
A prism like optic that maps None
to a removed focus when written.
val removed_option : ('F option, 'F, 'G, 'G) t
An optic that peels away Some
on read and removes None
on write.
val accept : ('F -> bool) -> ('F, 'F, 'F, 'F) t
A 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) t
A 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) t
The identity isomorphism.
Inverts the given optic. Raises when not given an invertible optic.
val reread : ('S -> 'F) -> ('S, 'F, 'T, 'T) t
An isomorphism that maps the focus with given function when read.
val rewrite : ('G -> 'T) -> ('S, 'S, 'G, 'T) t
An isomorphism that maps the focus with given function when written.
val normalize : ('S -> 'F) -> ('S, 'F, 'S, 'F) t
An isomorphism that maps the focus with given function in both ways.
val subset : ('S -> bool) -> ('S, 'S option, 'T, 'T) t
An isomorphism between values and values that pass the predicate.
val to_default : 'F -> ('F option, 'F, 'G, 'G) t
An isomorphism that maps None
to the given default value when read.
val of_default : 'G -> ('F, 'F, 'G, 'G option) t
An isomorphism that maps the given default value to None
when written.
val default : 'F -> ('F option, 'F, 'F, 'F option) t
An 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) t
An 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) t
TODO
val before : ('S -> unit) -> ('S, 'S, 'T, 'T) t
An identity like optic that performs a given side-effect when viewed.
val after : ?on_removed:(unit -> unit) -> ('T -> unit) -> ('S, 'S, 'T, 'T) t
An identity like optic that performs given side-effects when written.
val fold : 'R -> ('R -> 'F -> 'R) -> ('S, 'F, 'G, 'T) t -> 'S -> 'R
Folds over the focuses of the optic on the data.
# L.fold 0 ( + ) L.List.elems [ 3; 1; 4 ]
- : int = 8
val iter : ('S, 'F, 'G, 'T) t -> ('F -> unit) -> 'S -> unit
Iterates over the focuses of the optic on the data.
val count : ('S, 'F, 'G, 'T) t -> 'S -> int
Counts 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 list
Extracts a list of all the focuses of the optic on the data.
val exists : ('F -> bool) -> ('S, 'F, 'F, 'T) t -> 'S -> bool
Determines whether any focus of the optic on the data satisfy the predicate.
val forall : ('F -> bool) -> ('S, 'F, 'F, 'T) t -> 'S -> bool
Determines whether all focuces of the optic on the data satisfy the predicate.
val disjunction : ('S, bool, bool, 'T) t -> 'S -> bool
disjunction optic data
is equivalent to exists Fun.id optic data
.
val conjunction : ('S, bool, bool, 'T) t -> 'S -> bool
conjunction optic data
is equivalent to forall Fun.id optic data
.
val concat : string -> ('S, string, 'G, 'T) t -> 'S -> string
Concatenates all of the focuses of the optic on the data with given separator.
val fst : ('L1 * 'R, 'L1, 'L2, 'L2 * 'R) t
A lens focusing on the first element of a pair.
val snd : ('L * 'R1, 'R1, 'R2, 'L * 'R2) t
A 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) t
An isomorphism between pairs.
val elem_1_of_2 : ('F * 'X2, 'F, 'G, 'G * 'X2) t
val elem_2_of_2 : ('X1 * 'F, 'F, 'G, 'X1 * 'G) t
val elem_1_of_3 : ('F * 'X2 * 'X3, 'F, 'G, 'G * 'X2 * 'X3) t
val elem_2_of_3 : ('X1 * 'F * 'X3, 'F, 'G, 'X1 * 'G * 'X3) t
val elem_3_of_3 : ('X1 * 'X2 * 'F, 'F, 'G, 'X1 * 'X2 * 'G) t
val elem_1_of_4 : ('F * 'X2 * 'X3 * 'X4, 'F, 'G, 'G * 'X2 * 'X3 * 'X4) t
val elem_2_of_4 : ('X1 * 'F * 'X3 * 'X4, 'F, 'G, 'X1 * 'G * 'X3 * 'X4) t
val elem_3_of_4 : ('X1 * 'X2 * 'F * 'X4, 'F, 'G, 'X1 * 'X2 * 'G * 'X4) t
val elem_4_of_4 : ('X1 * 'X2 * 'X3 * 'F, 'F, 'G, 'X1 * 'X2 * 'X3 * 'G) t
val truncate : (float, int, int, float) t
An isomorphism between integers and floats.
module Array : sig ... end
module Either : sig ... end
module List : sig ... end
module Map : sig ... end
module Option : sig ... end
module Result : sig ... end
module String : sig ... end