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.
To compose optics we also define an ordinary function composition operator
let ( ^<< ) f g x = f (g x)
as one is not exposed by Loko
.
NOTE: The abstractions in this section serve auxiliary roles for the definition of optics.
type ('xs, 'x) iterator =
| Iterator : {
} -> ( 'xs, 'x ) iterator |
An iterator extracts elements of type 'x
one-by-one from a collection of type 'xs
.
module Iterator : sig ... end
type ('y, 'ys) builder =
| Builder : {
} -> ( 'y, 'ys ) builder |
A builder accumulates elements of type 'y
one-by-one to produce a collection of type 'ys
.
module Builder : sig ... end
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.
val partial_iso :
( 'S -> 'F option ) ->
( 'G -> 'T option ) ->
( 'S, 'F, 'G, 'T ) optic
Defines a new invertible partial isomorphism from a pair of partial conversions.
val iso : ( 'S -> 'F ) -> ( 'G -> 'T ) -> ( 'S, 'F, 'G, 'T ) optic
Defines a new invertible isomorphism from a pair of conversion functions.
let plus n = L.iso ((+) n) (Fun.flip (-) n)
let 3 = L.view (plus 1) 2
let 1 = L.review (plus 2) 3
let 1 = L.view (L.re (plus 2)) 3
val lens : ( 'S -> 'F ) -> ( 'G -> 'S -> 'T ) -> ( 'S, 'F, 'G, 'T ) optic
Defines a new lens from a getter and setter.
val getter : ( 'S -> 'F ) -> ( 'S, 'F, 'G, 'S ) optic
Defines a new getter.
val fold_lens :
( ( 'S, 'E, 'G, 'T ) optic -> 'S -> 'F ) ->
( 'S, 'E, 'G, 'T ) optic ->
( 'S, 'F, 'G, 'T ) optic
fold_lens fold traversal
defines a lens out of a suitable fold
and a traversal
.
val prism :
( 'S -> [< `Hit of 'F | `Miss of 'T ] ) ->
( 'G -> 'T ) ->
( 'S, 'F, 'G, 'T ) optic
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
`Hit (Filename.chop_suffix string suffix)
else `Miss string)
(fun prefix -> prefix ^ suffix)
let "Loko" = L.view (ends_with ".ml") "Loko.ml"
let "Loco.ml" = L.set (ends_with ".ml") "Loco" "Loko.ml"
let false = L.can_view (ends_with ".ml") "Loko.mli"
let "Loko.mli" = L.set (ends_with ".ml") "Loco" "Loko.mli"
Defines a new traversal from an iterator-builder pair.
val branch'2 :
( 'F1, 'F, 'G, 'G1 ) optic ->
( 'F2, 'F, 'G, 'G2 ) optic ->
( 'F1 * 'F2, 'F, 'G, 'G1 * 'G2 ) optic
Defines a new traversal over the elements of a 2-tuple.
val branch'3 :
( 'F1, 'F, 'G, 'G1 ) optic ->
( 'F2, 'F, 'G, 'G2 ) optic ->
( 'F3, 'F, 'G, 'G3 ) optic ->
( 'F1 * 'F2 * 'F3, 'F, 'G, 'G1 * 'G2 * 'G3 ) optic
Defines a new traversal over the elements of a 3-tuple.
val branch'4 :
( 'F1, 'F, 'G, 'G1 ) optic ->
( 'F2, 'F, 'G, 'G2 ) optic ->
( 'F3, 'F, 'G, 'G3 ) optic ->
( 'F4, 'F, 'G, 'G4 ) optic ->
( 'F1 * 'F2 * 'F3 * 'F4, 'F, 'G, 'G1 * 'G2 * 'G3 * 'G4 ) optic
Defines a new traversal over the elements of a 4-tuple.
val can_view : ( 'S, 'F, 'G, 'T ) optic -> 'S -> bool
Determines whether the optic has a focus on the data.
val view : ( 'S, 'F, 'G, 'T ) optic -> '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 ) optic -> 'S -> 'F option
Attempts to extract the first focus of the optic on the data.
val can_review : ( 'S, 'F, 'G, 'T ) optic -> 'G -> bool
Determines whether the optic has an inverse focus on the data.
val review : ( 'S, 'F, 'G, 'T ) optic -> '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 ) optic -> '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 ) optic -> ( 'F -> 'G ) -> 'S -> bool
Determines whether the focuses of the optic on the data can be updated.
val over : ( 'S, 'F, 'G, 'T ) optic -> ( 'F -> 'G ) -> 'S -> 'T
Updates the focuses of the optic on the data. Raises when cannot.
val over_default : ( 'S, 'F, 'G, 'S ) optic -> ( 'F -> 'G ) -> 'S -> 'S
Updates the focuses of the optic on the data. Returns input when cannot.
val over_opt : ( 'S, 'F, 'G, 'T ) optic -> ( 'F -> 'G ) -> 'S -> 'T option
Attempts to update the focuses of the optic on the data.
val can_set : ( 'S, 'F, 'G, 'T ) optic -> 'G -> 'S -> bool
Determines whether the focuses of the optic on the data can be set.
val set : ( 'S, 'F, 'G, 'T ) optic -> 'G -> 'S -> 'T
Sets the focuses of the optic on the data. Raises when cannot.
val set_default : ( 'S, 'F, 'G, 'S ) optic -> 'G -> 'S -> 'S
Sets the focuses of the optic on the data. Returns input when cannot.
val set_opt : ( 'S, 'F, 'G, 'T ) optic -> 'G -> 'S -> 'T option
Attempts to set the focuses of the optic on the data.
val can_remove : ( 'S, 'F, 'G, 'T ) optic -> 'S -> bool
Determines whether the focuses of the optic on the data can be removed.
val remove : ( 'S, 'F, 'G, 'T ) optic -> 'S -> 'T
Removes the focuses of the optic on the data. Raises when cannot.
val remove_default : ( 'S, 'F, 'G, 'S ) optic -> 'S -> 'S
Removes the focuses of the optic on the data. Returns input when cannot.
val remove_opt : ( 'S, 'F, 'G, 'T ) optic -> 'S -> 'T option
Attempts to remove the focuses of the optic on the data.
val disperse : ( 'S, 'F, 'G, 'T ) optic -> 'G array -> 'S -> 'T
Injects array elements to the focuses or removes them. Raises when cannot.
val disperse_keep : ( 'S, 'F, 'F, 'T ) optic -> '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 ) optic -> 'S -> 'T
transform optic data
is equivalent to over optic Fun.id data
.
val remove_op : ( 'S, 'F, 'G, 'T ) optic
Signal removal of current focus.
val over_op : ( 'S -> 'T ) -> ( 'S, 'F, 'G, 'T ) optic
Update focus with given function.
val set_op : 'T -> ( 'S, 'F, 'G, 'T ) optic
Update focus with given value.
A non-isomorphism computed from the focus.
val if_else :
( 'S -> bool ) ->
( 'S, 'F, 'G, 'T ) optic ->
( 'S, 'F, 'G, 'T ) optic ->
( 'S, 'F, 'G, 'T ) optic
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
.
val tuple'2 :
( 'S, 'L1, 'L2, 'S ) optic ->
( 'S, 'R1, 'R2, 'T ) optic ->
( 'S, 'L1 * 'R1, 'L2 * 'R2, 'T ) optic
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
.
let 9 =
L.transform (L.over_op (( + ) 2) |> L.and_then (L.over_op (( * ) 3))) 1
let ("1", "2") =
L.transform ((L.fst |> L.and_then L.snd) ^<< L.over_op Int.to_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) optic_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 ) optic ->
( ( 'S, 'C, 'C, 'U ) optic -> ( 'S, 'F, 'G, 'T ) optic ) ->
( 'S, 'C, 'C, 'U ) optic ->
( 'S, 'F, 'G, 'T ) optic
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 ) optic
An optic that never has a focus.
val removed_if : ( 'G -> bool ) -> ( 'F, 'F, 'G, 'G ) optic
An identity like optic that signals removal when written value matches predicate.
val as_removed : 'G -> ( 'F, 'F, 'G, 'G ) optic
A prism like optic that signals removal when written with equal value.
val removed_as : 'G -> ( 'F, 'F, 'G, 'G ) optic
A prism like optic that maps a removed focus to given value when written.
val removed_as_none : ( 'F, 'F, 'G, 'G option ) optic
A prism like optic that maps a removed focus to None
when written.
val none_as_removed : ( 'F, 'F, 'G option, 'G ) optic
A prism like optic that maps None
to a removed focus when written.
val removed_option : ( 'F option, 'F, 'G, 'G ) optic
An optic that peels away Some
on read and removes None
on write.
val accept : ( 'F -> bool ) -> ( 'F, 'F, 'F, 'F ) optic
A prism with a focus only when it passes the given predicate.
let [3; 1; 4; 1] =
L.remove (L.List.elems ^<< L.accept (fun x -> 4 < x)) [5; 3; 1; 6; 4; 1]
val reject : ( 'F -> bool ) -> ( 'F, 'F, 'F, 'F ) optic
A prism with a focus except when it passes the given predicate.
let [3; 1; 4; 1] =
L.remove (L.List.elems ^<< L.reject (fun x -> x < 5)) [5; 3; 1; 6; 4; 1]
val id : ( 'S, 'S, 'T, 'T ) optic
The identity isomorphism.
Inverts the given optic. Raises when not given an invertible optic.
val reread : ( 'S -> 'F ) -> ( 'S, 'F, 'T, 'T ) optic
An isomorphism that maps the focus with given function when read.
val rewrite : ( 'G -> 'T ) -> ( 'S, 'S, 'G, 'T ) optic
An isomorphism that maps the focus with given function when written.
val normalize : ( 'S -> 'F ) -> ( 'S, 'F, 'S, 'F ) optic
An isomorphism that maps the focus with given function in both ways.
val subset : ( 'S -> bool ) -> ( 'S, 'S option, 'T, 'T ) optic
An isomorphism between values and values that pass the predicate.
val to_default : 'F -> ( 'F option, 'F, 'G, 'G ) optic
An isomorphism that maps None
to the given default value when read.
val of_default : 'G -> ( 'F, 'F, 'G, 'G option ) optic
An isomorphism that maps the given default value to None
when written.
val default : 'F -> ( 'F option, 'F, 'F, 'F option ) optic
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 ) optic
An isomorphism between given values and booleans. Only truthy
maps to true
when read.
val apply_at :
( 'S, 'Si, 'Fi, 'F ) optic ->
( 'G, 'Gi, 'Ti, 'T ) optic ->
( 'Si, 'Fi, 'Gi, 'Ti ) optic ->
( 'S, 'F, 'G, 'T ) optic
TODO
val before : ( 'S -> unit ) -> ( 'S, 'S, 'T, 'T ) optic
An identity like optic that performs a given side-effect when viewed.
val after :
?on_removed:( unit -> unit ) ->
( 'T -> unit ) ->
( 'S, 'S, 'T, 'T ) optic
An identity like optic that performs given side-effects when written.
val fold : 'R -> ( 'R -> 'F -> 'R ) -> ( 'S, 'F, 'G, 'T ) optic -> 'S -> 'R
Folds over the focuses of the optic on the data.
let 8 = L.fold 0 (+) L.List.elems [3; 1; 4]
val iter : ( 'S, 'F, 'G, 'T ) optic -> ( 'F -> unit ) -> 'S -> unit
Iterates over the focuses of the optic on the data.
val count : ( 'S, 'F, 'G, 'T ) optic -> '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 ) optic -> 'S -> 'F list
Extracts a list of all the focuses of the optic on the data.
val exists : ( 'F -> bool ) -> ( 'S, 'F, 'F, 'T ) optic -> 'S -> bool
Determines whether any focus of the optic on the data satisfy the predicate.
val forall : ( 'F -> bool ) -> ( 'S, 'F, 'F, 'T ) optic -> 'S -> bool
Determines whether all focuces of the optic on the data satisfy the predicate.
val disjunction : ( 'S, bool, bool, 'T ) optic -> 'S -> bool
disjunction optic data
is equivalent to exists Fun.id optic data
.
val conjunction : ( 'S, bool, bool, 'T ) optic -> 'S -> bool
conjunction optic data
is equivalent to forall Fun.id optic data
.
val concat : string -> ( 'S, string, 'G, 'T ) optic -> 'S -> string
Concatenates all of the focuses of the optic on the data with given separator.
val fst : ( 'L1 * 'R, 'L1, 'L2, 'L2 * 'R ) optic
A lens focusing on the first element of a pair.
val snd : ( 'L * 'R1, 'R1, 'R2, 'L * 'R2 ) optic
A lens focusing on the second element of a pair.
val iso_pair :
( 'SL, 'FL, 'GL, 'TL ) optic ->
( 'SR, 'FR, 'GR, 'TR ) optic ->
( 'SL * 'SR, 'FL * 'FR, 'GL * 'GR, 'TL * 'TR ) optic
An isomorphism between pairs.
val elem_1_of_2 : ( 'F * 'X2, 'F, 'G, 'G * 'X2 ) optic
val elem_2_of_2 : ( 'X1 * 'F, 'F, 'G, 'X1 * 'G ) optic
val elem_1_of_3 : ( 'F * 'X2 * 'X3, 'F, 'G, 'G * 'X2 * 'X3 ) optic
val elem_2_of_3 : ( 'X1 * 'F * 'X3, 'F, 'G, 'X1 * 'G * 'X3 ) optic
val elem_3_of_3 : ( 'X1 * 'X2 * 'F, 'F, 'G, 'X1 * 'X2 * 'G ) optic
val elem_1_of_4 : ( 'F * 'X2 * 'X3 * 'X4, 'F, 'G, 'G * 'X2 * 'X3 * 'X4 ) optic
val elem_2_of_4 : ( 'X1 * 'F * 'X3 * 'X4, 'F, 'G, 'X1 * 'G * 'X3 * 'X4 ) optic
val elem_3_of_4 : ( 'X1 * 'X2 * 'F * 'X4, 'F, 'G, 'X1 * 'X2 * 'G * 'X4 ) optic
val elem_4_of_4 : ( 'X1 * 'X2 * 'X3 * 'F, 'F, 'G, 'X1 * 'X2 * 'X3 * 'G ) optic
val truncate : ( float, int, int, float ) optic
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