package accessor_base

  1. Overview
  2. Docs

Module Accessor_baseSource

include module type of struct include Accessor end

Types

Sourcemodule General = Accessor.General
Sourcetype ('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
Sourcemodule O = Accessor.O

To use Accessor in your own code, it is recommended to add the following to your import.ml:

type constructor = [
  1. | `construct
]
type equality = [
  1. | `get
  2. | `map
  3. | `at_most_one
  4. | `at_least_one
  5. | `construct
  6. | `coerce
]
type field = [
  1. | `get
  2. | `map
  3. | `at_most_one
  4. | `at_least_one
]
type getter = [
  1. | `get
  2. | `at_least_one
  3. | `at_most_one
]
type isomorphism = [
  1. | `get
  2. | `map
  3. | `at_most_one
  4. | `at_least_one
  5. | `construct
]
type many = [
  1. | `get
  2. | `map
]
type many_getter = [
  1. | `get
]
type mapper = [
  1. | `map
]
type nonempty = [
  1. | `get
  2. | `map
  3. | `at_least_one
]
type nonempty_getter = [
  1. | `get
  2. | `at_least_one
]
type optional = [
  1. | `get
  2. | `map
  3. | `at_most_one
]
type optional_getter = [
  1. | `get
  2. | `at_most_one
]
type variant = [
  1. | `get
  2. | `map
  3. | `at_most_one
  4. | `construct
]
Sourceval (@>) : ('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:

  • An isomorphism composed with a field is a field.
  • A field composed with a variant is an optional.
  • A 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.

Sourceval (.@()) : '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.

Sourceval (.@?()) : '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.

Sourceval (.@*()) : '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.

Sourceval (.@()<-) : '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.

Sourceval id : ('a, 'a, _) General.t

id can be used as any kind of accessor. It is also the only way to summon an equality.

Sourceval 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.

Using accessors

Indices

Sourcemodule 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.

Sourcemodule Indexed = Accessor.Indexed
Sourcemodule 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.

Functions

Getting and Folding

Sourceval get : (Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> getter ]) General.t -> 'at -> 'a

get t at reads a value from at.

Sourceval geti : ('i -> 'a -> _, Base.unit -> 'at -> _, [> getter ]) General.t -> 'at -> 'i Index.t * 'a

geti t at reads a value and its index from at.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval matchi : ('i -> 'a -> _, Base.unit -> 'at -> 'bt, [> optional ]) General.t -> 'at -> ('i Index.t * 'a, 'bt) Base.Either.t

An indexed version of match_.

Sourceval 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.

Sourceval to_listi : ('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t -> 'at -> ('i Index.t * 'a) Base.list

An indexed version of to_list.

Sourceval 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.

Sourceval to_arrayi : ('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t -> 'at -> ('i Index.t * 'a) Base.array

An indexed version of to_array.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval length : (Base.unit -> _ -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t -> 'at -> Base.int

length t at returns the number of targets in at.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval hd : (Base.unit -> 'a -> _, Base.unit -> 'at -> _, [> nonempty_getter ]) General.t -> 'at -> 'a

hd t at returns the first targetted element of at.

Sourceval hdi : ('i -> 'a -> _, Base.unit -> 'at -> _, [> nonempty_getter ]) General.t -> 'at -> 'i Index.t * 'a

An indexed version of hd.

Sourceval 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.

Sourceval hd_optioni : ('i -> 'a -> _, Base.unit -> 'at -> _, [> many_getter ]) General.t -> 'at -> ('i Index.t * 'a) Base.option

An indexed version of hd_option.

Sourceval 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)
Sourceval 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.

Sourceval 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)
Sourceval 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).

Sourceval 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.

Sourceval 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).

Modifying

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval set : (_ -> _ -> 'b, Base.unit -> 'at -> 'bt, [> mapper ]) General.t -> 'at -> to_:'b -> 'bt

set t at ~to_ replaces targetted values inside at with to_.

Monadic and Applicative functions

Signatures

There are a number of signatures and functors in this section, all for the purpose of providing a wide variety of applicative/monadic functionality.

Sourcemodule Functor = Accessor.Functor
Sourcemodule Applicative = Accessor.Applicative
Sourcemodule Applicative_without_return = Accessor.Applicative_without_return
Sourcemodule 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.

Sourcemodule Monad_without_return = Accessor.Monad_without_return
Functors
Sourcemodule 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.

Sourcemodule Of_functor2 = Accessor.Of_functor2
Sourcemodule Of_functor3 = Accessor.Of_functor3
Sourcemodule 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.

Sourcemodule Of_applicative2 = Accessor.Of_applicative2

See Of_applicative.

Sourcemodule Of_applicative3 = Accessor.Of_applicative3

See Of_applicative.

Sourcemodule Of_monad = Accessor.Of_monad

Of_monad is similar to Of_applicative. There are two differences.

Sourcemodule Of_monad2 = Accessor.Of_monad2

See Of_monad.

Sourcemodule Of_monad3 = Accessor.Of_monad3

See Of_monad.

Sourcemodule Of_applicative_without_return = Accessor.Of_applicative_without_return

Like Of_applicative, but without return.

Sourcemodule Of_applicative_without_return2 = Accessor.Of_applicative_without_return2

Like Of_applicative2, but without return.

Sourcemodule Of_applicative_without_return3 = Accessor.Of_applicative_without_return3
Sourcemodule Of_monad_without_return = Accessor.Of_monad_without_return

Like Of_monad, but without return.

Sourcemodule Of_monad_without_return2 = Accessor.Of_monad_without_return2

Like Of_monad2, but without return.

Sourcemodule Of_monad_without_return3 = Accessor.Of_monad_without_return3

Recursive update

Sourceval 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.

Sourceval 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.

Type equality

Sourcemodule 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.

Sourceval 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.

Construction

Sourceval 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.

Custom mappings

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)
Sourcemodule Equality = Accessor.Equality

An equality can transform any mapping. There is no need for you to provide any functionality of your own.

Sourcemodule Isomorphism = Accessor.Isomorphism
Sourcemodule Field = Accessor.Field
Sourcemodule Variant = Accessor.Variant
Sourcemodule Constructor = Accessor.Constructor
Sourcemodule Getter = Accessor.Getter
Sourcemodule Optional = Accessor.Optional
Sourcemodule Optional_getter = Accessor.Optional_getter
Sourcemodule Nonempty = Accessor.Nonempty
Sourcemodule Nonempty_getter = Accessor.Nonempty_getter
Sourcemodule Many = Accessor.Many
Sourcemodule Many_getter = Accessor.Many_getter
Sourcemodule Mapper = Accessor.Mapper

Creating accessors

Avoiding the value restriction

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 })]

Deriving accessors

ppx_accessor adds the ability to derive accessors given a type definition. See the ppx_accessor README for more information.

"Well behaved" accessors

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.

Creation functions

Field accessors

Sourceval 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
Sourceval field' : ('at -> 'a * ('b -> 'bt)) -> ('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< field ]) General.t

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.

Sourceval 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.

Sourceval 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.

Sourceval fieldi' : ('at -> 'i * 'a * ('b -> 'bt)) -> (('i * 'it) -> 'a -> 'b, 'it -> 'at -> 'bt, [< field ]) General.t

fieldi' is the indexed version of field'.

Sourceval 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.

Variant accessors

Sourceval 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
  • if match_ at = First a then construct a = at
  • if match_ at = Second bt then at = bt
Sourceval 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.

Optional accessors

Sourceval 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)
  • if match_ at = First a then set at a = at
  • if match_ at = Second bt then at = bt and set at b = at
  • set (set at a) b = set at b
Sourceval 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.

Sourceval 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.

Sourceval 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'.

Sourceval 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.

Sourceval 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.

Isomorphism accessors

Sourceval 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
Sourceval 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.

Sourceval 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.

Mapper accessors

Sourceval 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
Sourceval 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 accessors

Sourceval many : ('at -> ('bt, 'a, 'b) Many.t) -> ('i -> 'a -> 'b, 'i -> 'at -> 'bt, [< many ]) General.t

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)
Sourceval 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

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.

Sourceval 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)
Sourceval 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 accessors

Sourceval getter : ('at -> 'a) -> ('i -> 'a -> _, 'i -> 'at -> _, [< getter ]) General.t

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.

Sourceval getteri : ('at -> 'i * 'a) -> (('i * 'it) -> 'a -> _, 'it -> 'at -> _, [< getter ]) General.t

getteri is the indexed version of getter.

Optional getter accessors

Sourceval 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.

Sourceval 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.

Many getter accessors

Sourceval 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))
Sourceval 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

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.

Sourceval 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))
Sourceval 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.

Constructor accessors

Sourceval 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.

Sourceval 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.

Transforming accessors

Sourceval 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.

Sourceval 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.

Sourceval 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.

Sourceval many_to_list_field : (Base.unit, 'a, 'at, [> many ]) t -> (_, 'a Base.list, 'at, [< field ]) t

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.

Sourcemodule Bool : sig ... end
Sourcemodule Either : sig ... end
Sourcemodule Error : sig ... end
Sourcemodule Float : sig ... end
Sourcemodule Fn : sig ... end
Sourcemodule Info : sig ... end
Sourcemodule Int : sig ... end

The below functions all access modified versions of an int.

Sourcemodule List : sig ... end

See also: Accessor_core.List

Sourcemodule Map : sig ... end

See also: Accessor_core.Map

Sourcemodule Maybe_bound : sig ... end
Sourcemodule Option : sig ... end
Sourcemodule Or_error : sig ... end

ok and error are the same as Result.ok and Result.error, but specialized for Or_error.

Sourcemodule Ordering : sig ... end
Sourcemodule Result : sig ... end
Sourcemodule Sequence : sig ... end
Sourcemodule Set : sig ... end
Sourcemodule Sexp : sig ... end
Sourcemodule Sign : sig ... end
Sourcemodule Sign_or_nan : sig ... end
Sourcemodule Source_code_position : sig ... end
Sourcemodule Staged : sig ... end
Sourcemodule String : sig ... end
Sourcemodule Tuple2 : sig ... end
OCaml

Innovation. Community. Security.