Legend:
Library
Module
Module type
Parameter
Class
Class type
Library
Module
Module type
Parameter
Class
Class type
include module type of struct include Accessor end
module General = Accessor.General
type ('index, 'inner, 'outer, 'kind) t =
('index -> 'inner -> 'inner, 'index -> 'outer -> 'outer, 'kind) General.t
Accessors are commonly not indexed and don't need to support polymorphic updates. In such cases, it may be easier to read and write types in terms of t
instead of General.t
. Here is an example where the improvement by using t
is significant:
val date_ofday
: Time.Zone.t
-> ( 'i -> Date.t * Time.Ofday.t -> Date.t * Time.Ofday.t
, 'i -> Time.t -> Time.t
, [< isomorphism] )
Accessor.General.t
It is more cleanly written like this:
val date_ofday
: Time.Zone.t
-> (_, Date.t * Time.Ofday.t, Time.t, [< isomorphism]) Accessor.t
module O = Accessor.O
To use Accessor
in your own code, it is recommended to add the following to your import.ml:
To use Accessor
in your own code, it is recommended to add the following to your import.ml:
module Accessor =
(* Consider using something like [Accessor_base], [Accessor_core], or
[Accessor_async], instead. *)
Accessor
include Accessor.O
The O
module contains a few operators and type aliases that are unlikely to clash with anything else.
To use Accessor
in your own code, it is recommended to add the following to your import.ml:
module Accessor =
(* Consider using something like [Accessor_base], [Accessor_core], or
[Accessor_async], instead. *)
Accessor
include Accessor.O
The O
module contains a few operators and type aliases that are unlikely to clash with anything else.
val (@>) :
('middle, 'outer, 'kind) Accessor.General.t ->
('inner, 'middle, 'kind) Accessor.General.t ->
('inner, 'outer, 'kind) Accessor.General.t
a @> b
is the composition of the two accessors a
and b
. From left to right, a chain of composed accessors goes from outermost to innermost values. The resulting accessor kind is determined by the least powerful argument. Here are a few examples:
isomorphism
composed with a field
is a field
.field
composed with a variant
is an optional
.getter
composed with a variant
is an optional_getter
.It's normally more intuitive to think of the operations you need than to think of exactly which kind of accessor you are creating. For example, if you are trying to extract a value from a data structure using a field
, you would probably use get
. However, if you compose the field
with an optional
, get
no longer makes sense; you must use something like get_option
, instead.
The non-operator name is Accessor.compose
.
val (.@()) :
'at ->
(Base.unit -> 'a -> 'b, Base.unit -> 'at -> 'bt, [> getter ])
Accessor.General.t ->
'a
x.@(t)
extracts a single value from x
as identified by t
. The non-operator name is Accessor.get
.
val (.@?()) :
'at ->
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> optional_getter ])
Accessor.General.t ->
'a Base.option
x.@?(t)
extracts at most one value from x
as identified by t
. The non-operator name is Accessor.get_option
.
val (.@*()) :
'at ->
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ])
Accessor.General.t ->
'a Base.list
x.@*(t)
extracts any number of values from x
as identified by t
. The non-operator name is Accessor.to_list
.
val (.@()<-) :
'at ->
(_ -> _ -> 'b, Base.unit -> 'at -> 'bt, [> mapper ]) Accessor.General.t ->
'b ->
'bt
x.@(t) <- y
replaces any number of values in x
with y
, as identified by t
. The non-operator name is Accessor.set
.
val id : ('a, 'a, _) General.t
id
can be used as any kind of accessor. It is also the only way to summon an equality
.
val compose :
('middle, 'outer, 'kind) General.t ->
('inner, 'middle, 'kind) General.t ->
('inner, 'outer, 'kind) General.t
compose
is the same as ( @> )
. See the documentation of ( @> )
for more information.
module Index = Accessor.Index
An Index.t
is a heterogeneous stack of values intended to serve as "breadcrumbs" that show how you got to some value currently being accessed inside a composite data structure. For example, if on the way in you traversed a Map.t
, one component of the index might be the key of the data being accessed.
module Indexed = Accessor.Indexed
module Subtyping = Accessor.Subtyping
The Subtyping
module contains all the types used for accessor subtyping. You shouldn't have to use it, but it's here for the documentation.
get t at
reads a value from at
.
geti t at
reads a value and its index from at
.
val get_option :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> optional_getter ]) General.t ->
'at ->
'a Base.option
get_option t at
reads a value from at
, if present.
val get_optioni :
('i -> 'a -> _, Base.unit -> 'at -> _, [> optional_getter ]) General.t ->
'at ->
('i Index.t * 'a) Base.option
get_optioni t at
reads a value and its index from at
, if present.
val match_ :
(Base.unit -> 'a -> _, Base.unit -> 'at -> 'bt, [> optional ]) General.t ->
'at ->
('a, 'bt) Base.Either.t
match_ t at
is like get_option
, but in the failure case it may be able to give you the input data structure with a different type.
val matchi :
('i -> 'a -> _, Base.unit -> 'at -> 'bt, [> optional ]) General.t ->
'at ->
('i Index.t * 'a, 'bt) Base.Either.t
An indexed version of match_
.
val to_list :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
'a Base.list
Extract all the values targetted by an accessor in some composite data structure into a list.
val to_listi :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
('i Index.t * 'a) Base.list
An indexed version of to_list
.
val to_array :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
'a Base.array
Extract all the values targetted by an accessor in some composite data structure into an array.
val to_arrayi :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
('i Index.t * 'a) Base.array
An indexed version of to_array
.
val fold :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
init:'acc ->
f:('acc -> 'a -> 'acc) ->
'acc
Fold across all the values targetted by an accessor with an accumulator.
val foldi :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
init:'acc ->
f:('i Index.t -> 'acc -> 'a -> 'acc) ->
'acc
Indexed version of fold.
val iter :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('a -> Base.unit) ->
Base.unit
Iterate over all the values targetted by an accessor, applying the function argument to each one.
val iteri :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('i Index.t -> 'a -> Base.unit) ->
Base.unit
An indexed version of iter
.
val length :
(Base.unit -> _ -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
Base.int
length t at
returns the number of targets in at
.
val is_empty :
(Base.unit -> _ -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
Base.bool
is_empty t at
is true
iff there are no targets in at
.
val sum :
(module Base.Container.Summable with type t = 'sum) ->
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('a -> 'sum) ->
'sum
sum (module Summable) t at ~f
returns the sum of f a
for all targets a
in at
.
val sumi :
(module Base.Container.Summable with type t = 'sum) ->
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('i Index.t -> 'a -> 'sum) ->
'sum
sumi
is the indexed version of sum
.
val count :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('a -> Base.bool) ->
Base.int
count t at ~f
returns the number of targets in at
for which f
evaluates to true.
val counti :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('i Index.t -> 'a -> Base.bool) ->
Base.int
counti
is the indexed version of count
.
val exists :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('a -> Base.bool) ->
Base.bool
exists t at ~f
returns true
iff there is a target in at
for which f
returns true
. This is a short-circuiting operation.
val existsi :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('i Index.t -> 'a -> Base.bool) ->
Base.bool
existsi
is the indexed version of exists
.
val for_all :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('a -> Base.bool) ->
Base.bool
for_all t at ~f
returns true
iff f
returns true
for all targets in at
. This is a short-circuiting operation.
val for_alli :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('i Index.t -> 'a -> Base.bool) ->
Base.bool
for_alli
is the indexed version of for_all
.
val find_map :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('a -> 'b Base.option) ->
'b Base.option
find_map
returns the first evaluation of f
that returns Some
.
val find_mapi :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('i Index.t -> 'a -> 'b Base.option) ->
'b Base.option
find_mapi
is the indexed version of find_map
.
val find :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('a -> Base.bool) ->
'a Base.option
find t at ~f
returns the first target in at
for which the evaluation of f
returns true
.
val findi :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
f:('i Index.t -> 'a -> Base.bool) ->
('i Index.t * 'a) Base.option
findi
is the indexed version of find
.
val min_elt :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> nonempty_getter ]) General.t ->
'at ->
compare:('a -> 'a -> Base.int) ->
'a
min_elt t at ~compare
uses compare
to compare each target in at
and returns the first target with the smallest value.
val min_elt_option :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
compare:('a -> 'a -> Base.int) ->
'a Base.option
min_elt_option t at ~compare
uses compare
to compare each target in at
and returns the first target with the smallest value, if any.
val max_elt :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> nonempty_getter ]) General.t ->
'at ->
compare:('a -> 'a -> Base.int) ->
'a
max_elt t at ~compare
uses compare
to compare each target in at
and returns the first target with the largest value.
val max_elt_option :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
compare:('a -> 'a -> Base.int) ->
'a Base.option
max_elt_option t at ~compare
uses compare
to compare each target in at
and returns the first target with the largest value, if any.
val hd :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> nonempty_getter ]) General.t ->
'at ->
'a
hd t at
returns the first targetted element of at
.
val hdi :
('i -> 'a -> _, Base.unit -> 'at -> _, [> nonempty_getter ]) General.t ->
'at ->
'i Index.t * 'a
An indexed version of hd
.
val hd_option :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
'a Base.option
hd_option t at
returns the first targetted element of at
, if any.
val hd_optioni :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
('i Index.t * 'a) Base.option
An indexed version of hd_option
.
val map_reduce :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
empty:'r ->
combine:('r -> 'r -> 'r) ->
f:('a -> 'r) ->
'r
map_reduce t at ~empty ~combine ~f
applies f
to each targetted value in at
and combines the results using combine
. The result is empty
if there were no values. empty
and combine
are expected to satisfy the following properties:
combine empty a = a
combine a empty = a
combine (combine a b) c = combine a (combine b c)
val map_reducei :
('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
empty:'r ->
combine:('r -> 'r -> 'r) ->
f:('i Index.t -> 'a -> 'r) ->
'r
An indexed version of map_reduce
.
val reduce :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t ->
'at ->
empty:'a ->
combine:('a -> 'a -> 'a) ->
'a
reduce t at ~empty ~combine
combines all accessed values in at
using combine
. The result is empty
if there were no values accessed. empty
and combine
are expected to satisfy the following properties:
combine empty a = a
combine a empty = a
combine (combine a b) c = combine a (combine b c)
val map_reduce_nonempty :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> nonempty_getter ]) General.t ->
'at ->
combine:('r -> 'r -> 'r) ->
f:('a -> 'r) ->
'r
map_reduce_nonempty t at ~combine ~f
applies f
to each targetted value in at
and combines the results using combine
. combine
is expected to satisfy the property: combine (combine a b) c = combine a (combine b c)
.
val map_reduce_nonemptyi :
('i -> 'a -> _, Base.unit -> 'at -> _, [> nonempty_getter ]) General.t ->
'at ->
combine:('r -> 'r -> 'r) ->
f:('i Index.t -> 'a -> 'r) ->
'r
An indexed version of map_reduce_nonempty
.
val reduce_nonempty :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> nonempty_getter ]) General.t ->
'at ->
combine:('a -> 'a -> 'a) ->
'a
reduce_nonempty t at ~combine
combines all accessed values in at
using combine
. combine
is expected to satisfy the property: combine (combine a b) c = combine a
(combine b c)
.
val map :
(Base.unit -> 'a -> 'b, Base.unit -> 'at -> 'bt, [> mapper ]) General.t ->
'at ->
f:('a -> 'b) ->
'bt
map t at ~f
applies f
to each targetted value inside at
, replacing it with the result.
val mapi :
('i -> 'a -> 'b, Base.unit -> 'at -> 'bt, [> mapper ]) General.t ->
'at ->
f:('i Index.t -> 'a -> 'b) ->
'bt
mapi
is the indexed version of map
.
val folding_map :
(Base.unit -> 'a -> 'b, Base.unit -> 'at -> 'bt, [> many ]) General.t ->
'at ->
init:'acc ->
f:('acc -> 'a -> 'acc * 'b) ->
'bt
folding_map
is a version of map
that threads an accumulator through calls to f
.
val folding_mapi :
('i -> 'a -> 'b, Base.unit -> 'at -> 'bt, [> many ]) General.t ->
'at ->
init:'acc ->
f:('i Index.t -> 'acc -> 'a -> 'acc * 'b) ->
'bt
folding_mapi
is the indexed version of folding_map
.
val fold_map :
(Base.unit -> 'a -> 'b, Base.unit -> 'at -> 'bt, [> many ]) General.t ->
'at ->
init:'acc ->
f:('acc -> 'a -> 'acc * 'b) ->
'acc * 'bt
fold_map
is a combination of fold
and map
that threads an accumulator through calls to f
.
val fold_mapi :
('i -> 'a -> 'b, Base.unit -> 'at -> 'bt, [> many ]) General.t ->
'at ->
init:'acc ->
f:('i Index.t -> 'acc -> 'a -> 'acc * 'b) ->
'acc * 'bt
fold_mapi
is the indexed version of fold_map
.
set t at ~to_
replaces targetted values inside at
with to_
.
There are a number of signatures and functors in this section, all for the purpose of providing a wide variety of applicative/monadic functionality.
module Functor = Accessor.Functor
module Applicative = Accessor.Applicative
module Applicative_without_return = Accessor.Applicative_without_return
module Monad = Accessor.Monad
The monad signatures differ from the applicative ones in that some of the functions have an optional how
argument. They always default to `Sequential
, which is the behavior that interleaves side effects with monadic effects. If you override this argument to `Parallel
then all the side effects are performed up front, and then the results are combined.
module Monad_without_return = Accessor.Monad_without_return
module Of_functor = Accessor.Of_functor
Of_functor
, Of_functor2
, and Of_functor3
generate map-like functions that work under some "functor", which is like a monad or applicative, except that it only supports map
.
module Of_functor2 = Accessor.Of_functor2
module Of_functor3 = Accessor.Of_functor3
module Of_applicative = Accessor.Of_applicative
Of_applicative
and Of_applicative2
can be used to generate map-like functions that can use applicative effects. See also Of_monad
, which gives more control over the relationship between side effects and monadic effects.
module Of_applicative2 = Accessor.Of_applicative2
See Of_applicative
.
module Of_applicative3 = Accessor.Of_applicative3
See Of_applicative
.
module Of_monad = Accessor.Of_monad
Of_monad
is similar to Of_applicative
. There are two differences.
module Of_monad2 = Accessor.Of_monad2
See Of_monad
.
module Of_monad3 = Accessor.Of_monad3
See Of_monad
.
module Of_applicative_without_return = Accessor.Of_applicative_without_return
Like Of_applicative
, but without return
.
module Of_applicative_without_return2 = Accessor.Of_applicative_without_return2
Like Of_applicative2
, but without return
.
module Of_applicative_without_return3 = Accessor.Of_applicative_without_return3
module Of_monad_without_return = Accessor.Of_monad_without_return
Like Of_monad
, but without return
.
module Of_monad_without_return2 = Accessor.Of_monad_without_return2
Like Of_monad2
, but without return
.
module Of_monad_without_return3 = Accessor.Of_monad_without_return3
val transform :
(Base.unit -> 'a -> 'b, Base.unit -> 'a -> 'b, [> mapper ]) General.t ->
'a ->
f:('b -> 'b) ->
'b
transform t a ~f
applies f
everywhere it can inside of a
once. It operates from the bottom up in one pass. t
is used to find the children at each level, where the children are expected to have the same type as their parent.
val rewrite :
(Base.unit -> 'a -> 'b, Base.unit -> 'a -> 'b, [> mapper ]) General.t ->
'a ->
f:('b -> 'a Base.option) ->
'b
rewrite t a ~f
applies the rewrite rule f
everywhere it can inside of a
until it cannot be applied anywhere else. It operates from the bottom up, retrying subtrees each time a rule is applied successfully. t
is used to find the children at each level, where the children are expected to have the same type as their parent.
module Identical = Accessor.Identical
An Identical.t
is similar to a Type_equal.t
, but it relates two pairs of types with each other instead of merely two types. It is a more natural way of using an equality accessor than Type_equal.t
would be, since you only need to match on one constructor.
val identical :
(Base.unit -> 'a -> 'b, Base.unit -> 'at -> 'bt, [> equality ]) General.t ->
('a, 'b, 'at, 'bt) Identical.t
An equality is more powerful even than an isomorphism. It can be used to prove that the types are equal using the identical
function.
val construct :
(_ -> _ -> 'b, _ -> _ -> 'bt, [> constructor ]) General.t ->
'b ->
'bt
construct
goes the opposite way to most access patterns. It allows you to construct a composite data structure without reading from one.
Accessors transform a mapping over inner data to a mapping over outer data. You can use accessors to transform your own mapping types by using the functors in this section. Here is an example of using Mapper.Make
to define functions equivalent to Accessor.map
and Accessor.mapi
:
include Mapper.Make (struct
type ('a, 'b) t = 'a -> 'b
let mapper map t at = map at ~f:t
end)
let mapi t at ~f = access t (fun (i, a) -> f i a) ([], at)
let map t at ~f = mapi t at ~f:(fun [] a -> f a)
module Equality = Accessor.Equality
An equality
can transform any mapping. There is no need for you to provide any functionality of your own.
module Isomorphism = Accessor.Isomorphism
module Field = Accessor.Field
module Variant = Accessor.Variant
module Constructor = Accessor.Constructor
module Getter = Accessor.Getter
module Optional = Accessor.Optional
module Optional_getter = Accessor.Optional_getter
module Nonempty = Accessor.Nonempty
module Nonempty_getter = Accessor.Nonempty_getter
module Many = Accessor.Many
module Many_getter = Accessor.Many_getter
module Mapper = Accessor.Mapper
The value restriction will apply frequently to accessors you define. Unfortunately, even if you are not defining an accessor supporting polymorphic update, polymorphism is still critical for the normal type checking of accessors, because without it there could be no subtyping. Accessor
addresses this problem by exposing its representation as a function and offering a syntax extension, as part of ppx_accessor, to eta expand the definition for you. The upshot is that you can define accessors like this and not think about the value restriction anymore:
let foo =
[%accessor
Accessor.field ~get:(fun t -> t.foo) ~set:(fun t foo -> { t with foo })]
ppx_accessor adds the ability to derive accessors given a type definition. See the ppx_accessor README for more information.
Many of the functions for creating accessors are documented with conditions that are necessary for an accessor to be "well behaved". For most accessors, these conditions are sufficiently restrictive that the type parameters are not quite freely independent of each other.
The properties generally make intuitive sense, but it can still be useful sometimes to define an accessor that is not always well behaved. Even Accessor
itself defines a few badly behaved accessors. If you define an accessor that isn't well behaved, it is recommended that you document the conditions under which it is not well behaved.
val field :
get:('at -> 'a) ->
set:('at -> 'b -> 'bt) ->
('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< field ]) General.t
field ~get ~set
creates a field accessor. A field accesses exactly one value within a composite data structure. For the field to be well behaved, get
and set
should satisfy the following properties:
get (set at a) = a
set at (get at) = at
set (set at a) b = set at b
field'
is the same as field
, just with a slightly different interface. field
is usually more convenient to use, but field'
can be useful to allow get
and set
to share the computation of finding the location to modify.
val of_field :
([> `Set_and_create ], 'r, 'a) Base.Field.t_with_perm ->
('i -> 'a -> 'a, 'i -> 'r -> 'r, [< field ]) General.t
A Field.t
is sufficient to define a field accessor, but the resulting accessor might not be as polymorphic as it could have been if defined by hand or using @@deriving accessor
.
val fieldi :
get:('at -> 'i * 'a) ->
set:('at -> 'b -> 'bt) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< field ]) General.t
fieldi
is the indexed version of field
.
val fieldi' :
('at -> 'i * 'a * ('b -> 'bt)) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< field ]) General.t
fieldi'
is the indexed version of field'
.
val of_fieldi :
([> `Set_and_create ], 'r, 'a) Base.Field.t_with_perm ->
((Base.string * 'it) -> 'a -> 'a, 'it -> 'r -> 'r, [< field ]) General.t
A Field.t
is sufficient to define an indexed field accessor, where the index is the name of the field as a string. The resulting accessor might not be as polymorphic as it could have been if defined by hand or using @@deriving accessor
.
val variant :
match_:('at -> ('a, 'bt) Base.Either.t) ->
construct:('b -> 'bt) ->
('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< variant ]) General.t
variant ~match_ ~construct
creates a variant accessor. A variant accesses at most one value within a composite data structure, and if it does access a value then that value is representative of the entire data structure. A well behaved variant should satisfy the following properties:
match_ (construct a) = First a
match_ at = First a
then construct a = at
match_ at = Second bt
then at = bt
val varianti :
match_:('at -> ('i * 'a, 'bt) Base.Either.t) ->
construct:('b -> 'bt) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< variant ]) General.t
varianti
is the indexed version of variant
.
val optional :
match_:('at -> ('a, 'bt) Base.Either.t) ->
set:('at -> 'b -> 'bt) ->
('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< optional ]) General.t
optional ~match_ ~set
creates an optional accessor. An optional accesses at most one value within a composite data structure. A well behaved optional should satisfy the following properties:
match_ (set at a) = Either.First.map (match_ at) ~f:(const a)
match_ at = First a
then set at a = at
match_ at = Second bt
then at = bt
and set at b = at
set (set at a) b = set at b
val optional' :
('at -> ('a * ('b -> 'bt), 'bt) Base.Either.t) ->
('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< optional ]) General.t
optional'
is the same as optional
, just with a slightly different interface. optional
is usually more convenient to use, but optional'
can be useful to allow match_
and set
to share the computation of finding the location to modify.
val optionali :
match_:('at -> ('i * 'a, 'bt) Base.Either.t) ->
set:('at -> 'b -> 'bt) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< optional ]) General.t
optionali
is the indexed version of optional
.
val optionali' :
('at -> ('i * 'a * ('b -> 'bt), 'bt) Base.Either.t) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< optional ]) General.t
optionali'
is the indexed version of optional'
.
val filter_index :
('i Index.t -> Base.bool) ->
('i -> 'a -> 'a, 'i -> 'a -> 'a, [< optional ]) General.t
filter_index predicate
accesses the entire value if its index satisfies predicate
, otherwise it accesses nothing. Compose it with a many accessor to access a subset of values.
val filter_map_index :
('i Index.t -> 'j Index.t Base.option) ->
('j -> 'a -> 'a, 'i -> 'a -> 'a, [< optional ]) General.t
filter_map_index f
is like filter_index
, but it can also modify the indices.
val isomorphism :
get:('at -> 'a) ->
construct:('b -> 'bt) ->
('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< isomorphism ]) General.t
isomorphism ~get ~construct
creates an isomorphism accessor. An isomorphism accesses exactly one value which exactly represents the entire data structure. A well behaved isomorphism should satisfy the following properties:
get (construct b) = b
construct (get at) = at
val isomorphismi :
get:('at -> 'i * 'a) ->
construct:('b -> 'bt) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< isomorphism ]) General.t
isomorphismi
is the indexed version of isomorphism
.
val map_index :
('i Index.t -> 'j Index.t) ->
('j -> 'a -> 'b, 'i -> 'a -> 'b, [< isomorphism ]) General.t
map_index f
applies f
to the the indices that pass through it in a chain of composed accessors.
val mapper :
('at -> f:('a -> 'b) -> 'bt) ->
('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< mapper ]) General.t
mapper map
creates a mapper accessor. A mapper can modify values inside a composite data structure, but cannot read anything out. A well behaved mapper should satisfy the following properties:
map at ~f:Fn.id = at
map at ~f:(Fn.compose f g) = map (map at ~f:g) ~f
val mapperi :
('at -> f:('i -> 'a -> 'b) -> 'bt) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< mapper ]) General.t
mapperi
is the indexed version of mapper
.
many traverse
creates a many
accessor. A many
accesses any number of values within a composite data structure.
To define a many
accessor, you must use Accessor.Many.t
, which is an applicative. You should traverse the data structure as necessary, and each time you reach a value that should be accessed, apply Accessor.Many.access
to it.
Here is an example of using many
to define an accessor that reaches all the elements of a list:
Accessor.many (fun at -> Accessor.Many.all (List.map at ~f:Accessor.Many.access))
A well behaved many should satisfy the same properties as a well behaved mapper, but generalized for an applicative setting. The properties themselves are uselessly complicated when written out, but here they are anyway. A
and B
are assumed to have the of_many
function generated by Many.Of_applicative
, and Compose
is assumed to be some functor behaving like Applicative.Compose
that also uses Many.Of_applicative
to generate an of_many
function.
A.of_many (traverse at) ~access:A.return = A.return at
Compose(A)(B).of_many (traverse at) ~access:(fun a -> A.map (g a) ~f)
= A.map (A.of_many (traverse at) ~access:g) ~f:(fun at ->
B.of_many (traverse at) ~access:f)
val manyi :
('at -> ('bt, 'i * 'a, 'b) Many.t) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< many ]) General.t
manyi
is the indexed version of many
.
Nonempty accessors are defined very similarly to how many accessors are defined. The only difference is that you should use Accessor.Nonempty
instead of Accessor.Many
. The practical difference between the two is that Accessor.Nonempty
does not have a return
function.
val nonempty :
('at -> ('bt, 'a, 'b) Nonempty.t) ->
('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< nonempty ]) General.t
nonempty traverse
creates a nonempty accessor. A nonempty accesses a nonzero number of values within a composite data structure.
To define a nonempty
accessor, you must use Accessor.Nonempty.t
, which is an applicative lacking return
. You should traverse the data structure as necessary, and each time you reach a value that should be accessed, apply Accessor.Nonempty.access
to it.
Here is an example of using nonempty
to define an accessor that reaches both components of a tuple:
Accessor.nonempty (fun (a, b) ->
let open Accessor.Nonempty.Let_syntax in
let%map_open a = access a
and b = access b in
a, b)
A well behaved nonempty should satisfy the second property of a well behaved mapper, but generalized for an applicative setting. The property itself is uselessly complicated when written out, but here it is anyway. A
and B
are assumed to have the of_nonempty
function generated by Nonempty.Of_applicative_without_return
, and Compose
is assumed to be some functor behaving like Applicative_without_return.Compose
that also uses Nonempty.Of_applicative_without_return
to generate an of_nonempty
function.
Compose(A)(B).of_nonempty (traverse at) ~access:(fun a -> A.map (g a) ~f)
= A.map (A.of_nonempty (traverse at) ~access:g) ~f:(fun at ->
B.of_nonempty (traverse at) ~access:f)
val nonemptyi :
('at -> ('bt, 'i * 'a, 'b) Nonempty.t) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< nonempty ]) General.t
nonemptyi
is the indexed version of nonempty
.
getter get
creates a getter accessor. A getter reads exactly one value from a composite data structure. There are no properties necessary for a getter to be well behaved.
getteri
is the indexed version of getter
.
val optional_getter :
('at -> 'a Base.option) ->
('i -> 'a -> _, 'i -> 'at -> _, [< optional_getter ]) General.t
optional_getter get
creates an optional getter accessor. An optional getter reads at most one value from a composite data structure. There are no properties necessary for an optional getter to be well behaved.
val optional_getteri :
('at -> ('i * 'a) Base.option) ->
(('i * 'it) -> 'a -> _, 'it -> 'at -> _, [< optional_getter ]) General.t
optional_getteri
is the indexed version of optional_getter
.
val many_getter :
('at -> 'a Many_getter.t) ->
('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< many_getter ]) General.t
many_getter map_reduce
creates a many_getter accessor. A many getter reads any number of values from a composite data structure. There are no properties necessary for a many getter to be well behaved.
To define a many_getter, you must use the Many_getter
interface. Like Many
, it has an access
function to designate which values to access. Unlike Many
, instead of an applicative interface, it has empty
and append
(or ( @ )
) functions.
Here is an example of defining a getter that reads all the elements of a list:
Accessor.many_getter (fun at ->
Accessor.Many_getter.of_list (List.map at ~f:Accessor.Many_getter.access))
val many_getteri :
('at -> ('i * 'a) Many_getter.t) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< many_getter ]) General.t
many_getteri
is the indexed version of many_getter
.
Nonempty getter accessors are defined very similarly to how many getter accessors are defined. The only difference is that it uses Nonempty_getter
instead of Many_getter
. Nonempty_getter
does not have empty
.
val nonempty_getter :
('at -> 'a Nonempty_getter.t) ->
('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< nonempty_getter ]) General.t
nonempty_getter map_reduce
creates a nonempty getter accessor. A nonempty getter reads at least one value from a composite data structure. There are no properties necessary for a nonempty getter to be well behaved.
To define a nonempty_getter, you must use the Nonempty_getter
interface. Like Nonempty
, it has an access
function to designate which values to access. Unlike Nonempty
, instead of an applicative style interface, it has an append
(or ( @ )
) function.
Here is an example of defining a getter that reads both of the components of a tuple:
Accessor.nonempty_getter (fun (a, b) ->
Accessor.Nonempty_getter.(access a @ access b))
val nonempty_getteri :
('at -> ('i * 'a) Nonempty_getter.t) ->
(('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< nonempty_getter ]) General.t
nonempty_getteri
is the indexed version of nonempty_getter
.
val constructor :
('b -> 'bt) ->
(_ -> _ -> 'b, _ -> _ -> 'bt, [< constructor ]) General.t
constructor construct
creates a constructor accessor. A constructor creates a composite data structure from an argument. There are no properties necessary for a constructor to be well behaved.
val of_variant :
('b -> 'bt) Base.Variant.t ->
(_ -> _ -> 'b, _ -> _ -> 'bt, [< constructor ]) General.t
A Variant.t
is not sufficient to define a variant accessor, but is at least sufficient to define a constructor accessor.
val invert :
(Base.unit -> 'a -> 'b, Base.unit -> 'at -> 'bt, [> isomorphism ]) General.t ->
('i -> 'bt -> 'at, 'i -> 'b -> 'a, [< isomorphism ]) General.t
Turn an isomorphism around. invert (isomorphism ~get:f ~construct:g)
is isomorphism ~get:g ~construct:f
.
val getter_to_constructor :
(Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> getter ]) General.t ->
(_ -> _ -> 'at, _ -> _ -> 'a, [< constructor ]) General.t
Turn a getter into a constructor. getter_to_constructor (getter f)
is constructor
f
.
val constructor_to_getter :
(_ -> _ -> 'b, _ -> _ -> 'bt, [> constructor ]) General.t ->
('i -> 'bt -> _, 'i -> 'b -> _, [< getter ]) General.t
Turn a constructor into a getter. constructor_to_getter (constructor f)
is getter
f
.
Given a many
accessor, generate a field
accessor that accesses all the elements that would be accessed by the many
accessor in the form of a list. When replacing, if the list is too short then later elements in the data structure are left alone, and if the list is too long then extraneous elements are not used.
The resulting accessor is only well-behaved if you preserve the length of the list across getting and setting.
module Bool : sig ... end
module Either : sig ... end
module Error : sig ... end
module Float : sig ... end
module Fn : sig ... end
module Info : sig ... end
module Int : sig ... end
The below functions all access modified versions of an int
.
module List : sig ... end
See also: Accessor_core.List
module Map : sig ... end
See also: Accessor_core.Map
module Maybe_bound : sig ... end
module Option : sig ... end
module Or_error : sig ... end
ok
and error
are the same as Result.ok
and Result.error
, but specialized for Or_error
.
module Ordering : sig ... end
module Result : sig ... end
module Sequence : sig ... end
module Set : sig ... end
module Sexp : sig ... end
module Sign : sig ... end
module Sign_or_nan : sig ... end
module Source_code_position : sig ... end
module Staged : sig ... end
module String : sig ... end
module Tuple2 : sig ... end