jon.recoil.org

Module Core.MapSource

Map is a functional data structure (balanced binary tree) implementing finite maps over a totally-ordered domain, called a "key".

For example:

  let empty = Map.empty (module String)

  let numbers =
    Map.of_alist_exn
      (module String)
      [ "three", Substr "three"; "four", Substr "four" ]
  ;;

Note that the functions in Map are polymorphic over the type of the key and of the data; you just need to pass in the first-class module for the key type (here, String).

Suppose you wanted to define a new module Foo to use in a map. You would write:

  module Foo = struct
    module T = struct
      type t = int * int [@@deriving compare, sexp_of]
    end

    include T
    include Comparable.Make_plain (T)
  end

This gives you a module Foo with the appropriate comparator in it, and then this:

  let m = Map.empty (module Foo)

lets you create a map keyed by Foo. The reason you need to write a sexp-converter and a comparison function for this to work is that maps both need comparison and the ability to serialize the key for generating useful errors.

The interface

type (!'key, !+'value, !'cmp) t = ('key, 'value, 'cmp) Base.Map.t
val invariants : (_, _, _) Core.Map.t -> Base.Bool.t @@ portable

Test if invariants of internal weight-balanced search tree hold.

Sourceval comparator : ('a, _, 'cmp) Core.Map.t -> ('a, 'cmp) Core.Comparator.t @@ portable
Sourceval comparator_s : ('a, _, 'cmp) Core.Map.t -> ('a, 'cmp) Base.Comparator.Module.t @@ portable
val empty : ('a, 'cmp) Base.Comparator.Module.t -> ('a, 'b, 'cmp) Core.Map.t @@ portable

The empty map.

val singleton : ('a, 'cmp) Base.Comparator.Module.t -> 'a -> 'b -> ('a, 'b, 'cmp) Core.Map.t @@ portable

Map with one (key, data) pair.

val of_alist : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Base.List.t -> [ `Ok of ('a, 'b, 'cmp) Core.Map.t | `Duplicate_key of 'a ] @@ portable

Creates map from an association list with unique keys.

val of_alist_or_error : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Base.List.t -> ('a, 'b, 'cmp) Core.Map.t Core.Or_error.t @@ portable

Creates map from an association list with unique keys. Returns an error if duplicate 'a keys are found.

val of_alist_exn : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Base.List.t -> ('a, 'b, 'cmp) Core.Map.t @@ portable

Creates map from an association list with unique keys. Raises an exception if duplicate 'a keys are found.

Sourceval of_hashtbl_exn : ('a, 'cmp) Base.Comparator.Module.t -> ('a, 'b) Base.Hashtbl.t -> ('a, 'b, 'cmp) Core.Map.t @@ portable

of_hashtbl_exn creates a map from bindings present in a hash table. of_hashtbl_exn raises if there are distinct keys a1 and a2 in the table with comparator.compare a1 a2 = 0, which is only possible if the hash-table comparison function is different than comparator.compare. In the common case, the comparison is the same, in which case of_hashtbl_exn does not raise, regardless of the keys present in the table.

val of_alist_multi : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Base.List.t -> ('a, 'b Base.List.t, 'cmp) Core.Map.t @@ portable

Creates map from an association list with possibly repeated keys.

val of_alist_fold : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Base.List.t -> init:'c -> f:('c -> 'b -> 'c) @ local -> ('a, 'c, 'cmp) Core.Map.t @@ portable

Combines an association list into a map, folding together bound values with common keys.

val of_alist_reduce : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Base.List.t -> f:('b -> 'b -> 'b) @ local -> ('a, 'b, 'cmp) Core.Map.t @@ portable

Combines an association list into a map, reducing together bound values with common keys.

val of_iteri : ('a, 'cmp) Base.Comparator.Module.t -> iteri:(f:(key:'a -> data:'b -> Base.Unit.t) @ local -> Base.Unit.t) @ local -> [ `Ok of ('a, 'b, 'cmp) Core.Map.t | `Duplicate_key of 'a ] @@ portable

of_iteri ~iteri behaves like of_alist, except that instead of taking a concrete datastructure, it takes an iteration function. For instance, to convert a string table into a map: of_iteri (module String) ~iteri:(Hashtbl.iteri table). It is faster than adding the elements one by one.

val of_iteri_exn : ('a, 'cmp) Base.Comparator.Module.t -> iteri:(f:(key:'a -> data:'b -> Base.Unit.t) @ local -> Base.Unit.t) @ local -> ('a, 'b, 'cmp) Core.Map.t @@ portable

Like of_iteri except that it raises an exception if duplicate 'a keys are found.

Trees

Parallel to the map modules Map and Map.Poly, there are also tree modules Map.Tree and Map.Poly.Tree. A tree is a bare representation of a map, without the comparator. Thus tree operations need to obtain the comparator from somewhere. For Map.Poly.Tree, the comparator is implicit in the module name. For Map.Tree, the comparator must be passed to each operation.

The main advantages of trees over maps are slightly improved space usage (there is no outer container holding the comparator) and the ability to marshal trees, because a tree doesn't contain a closure, the way a map does.

The main disadvantages of using trees are needing to be more explicit about the comparator, and the possibility of accidentally using polymorphic equality on a tree (for which maps dynamically detect failure due to the presence of a closure in the data structure).

Sourcemodule Tree : sig ... end
Sourceval to_tree : ('k, 'v, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.Tree.t @@ portable
Sourceval of_tree : ('k, 'cmp) Base.Comparator.Module.t -> ('k, 'v, 'cmp) Core.Map.Tree.t -> ('k, 'v, 'cmp) Core.Map.t @@ portable

Creates a t from a Tree.t and a Comparator.t. This is an O(n) operation as it must discover the length of the Tree.t.

More interface

val of_sorted_array : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Base.Array.t -> ('a, 'b, 'cmp) Core.Map.t Core.Or_error.t @@ portable

Creates map from a sorted array of key-data pairs. The input array must be sorted, as given by the relevant comparator (either in ascending or descending order), and must not contain any duplicate keys. If either of these conditions does not hold, an error is returned.

val of_sorted_array_unchecked : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Base.Array.t -> ('a, 'b, 'cmp) Core.Map.t @@ portable

Like of_sorted_array except it returns a map with broken invariants when an Error would have been returned.

val of_increasing_iterator_unchecked : ('a, 'cmp) Base.Comparator.Module.t -> len:Base.Int.t -> f:(Base.Int.t -> 'a * 'b) @ local -> ('a, 'b, 'cmp) Core.Map.t @@ portable

of_increasing_iterator_unchecked c ~len ~f behaves like of_sorted_array_unchecked c (Array.init len ~f), with the additional restriction that a decreasing order is not supported. The advantage is not requiring you to allocate an intermediate array. f will be called with 0, 1, ... len - 1, in order.

val of_increasing_sequence : ('k, 'cmp) Base.Comparator.Module.t -> ('k * 'v) Core.Sequence.t -> ('k, 'v, 'cmp) Core.Map.t Core.Or_error.t @@ portable

of_increasing_sequence c seq behaves like of_sorted_array c (Sequence.to_array seq), but does not allocate the intermediate array.

The sequence will be folded over once, and the additional time complexity is O(n).

val of_sequence : ('k, 'cmp) Base.Comparator.Module.t -> ('k * 'v) Core.Sequence.t -> [ `Ok of ('k, 'v, 'cmp) Core.Map.t | `Duplicate_key of 'k ] @@ portable

Creates a map from an association sequence with unique keys.

of_sequence c seq behaves like of_alist c (Sequence.to_list seq) but does not allocate the intermediate list.

If your sequence is increasing, use of_increasing_sequence for better performance.

val of_sequence_or_error : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Core.Sequence.t -> ('a, 'b, 'cmp) Core.Map.t Core.Or_error.t @@ portable

Creates a map from an association sequence with unique keys, returning an error if duplicate 'a keys are found.

of_sequence_or_error c seq behaves like of_alist_or_error c (Sequence.to_list seq) but does not allocate the intermediate list.

val of_sequence_exn : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Core.Sequence.t -> ('a, 'b, 'cmp) Core.Map.t @@ portable

Creates a map from an association sequence with unique keys, raising an exception if duplicate 'a keys are found.

of_sequence_exn c seq behaves like of_alist_exn c (Sequence.to_list seq) but does not allocate the intermediate list.

val of_sequence_multi : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Core.Sequence.t -> ('a, 'b Base.List.t, 'cmp) Core.Map.t @@ portable

Creates a map from an association sequence with possibly repeated keys. The values in the map for a given key appear in the same order as they did in the association list.

of_sequence_multi c seq behaves like of_alist_multi c (Sequence.to_list seq) but does not allocate the intermediate list.

val of_sequence_fold : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Core.Sequence.t -> init:'c -> f:('c -> 'b -> 'c) @ local -> ('a, 'c, 'cmp) Core.Map.t @@ portable

Combines an association sequence into a map, folding together bound values with common keys.

of_sequence_fold c seq ~init ~f behaves like of_alist_fold c (Sequence.to_list seq) ~init ~f but does not allocate the intermediate list.

val of_sequence_reduce : ('a, 'cmp) Base.Comparator.Module.t -> ('a * 'b) Core.Sequence.t -> f:('b -> 'b -> 'b) @ local -> ('a, 'b, 'cmp) Core.Map.t @@ portable

Combines an association sequence into a map, reducing together bound values with common keys.

of_sequence_reduce c seq ~f behaves like of_alist_reduce c (Sequence.to_list seq) ~f but does not allocate the intermediate list.

val of_list_with_key : ('k, 'cmp) Base.Comparator.Module.t -> 'v Base.List.t -> get_key:('v -> 'k) @ local -> [ `Ok of ('k, 'v, 'cmp) Core.Map.t | `Duplicate_key of 'k ] @@ portable

Constructs a map from a list of values, where get_key extracts a key from a value.

val of_list_with_key_or_error : ('k, 'cmp) Base.Comparator.Module.t -> 'v Base.List.t -> get_key:('v -> 'k) @ local -> ('k, 'v, 'cmp) Core.Map.t Core.Or_error.t @@ portable

Like of_list_with_key; returns Error on duplicate key.

val of_list_with_key_exn : ('k, 'cmp) Base.Comparator.Module.t -> 'v Base.List.t -> get_key:('v -> 'k) @ local -> ('k, 'v, 'cmp) Core.Map.t @@ portable

Like of_list_with_key; raises on duplicate key.

val of_list_with_key_multi : ('k, 'cmp) Base.Comparator.Module.t -> 'v Base.List.t -> get_key:('v -> 'k) @ local -> ('k, 'v Base.List.t, 'cmp) Core.Map.t @@ portable

Like of_list_with_key; produces lists of all values associated with each key.

val of_list_with_key_fold : ('k, 'cmp) Base.Comparator.Module.t -> 'v Base.List.t -> get_key:('v -> 'k) @ local -> init:'acc -> f:('acc -> 'v -> 'acc) -> ('k, 'acc, 'cmp) Core.Map.t @@ portable

Like of_list_with_key; resolves duplicate keys the same way of_alist_fold does.

val of_list_with_key_reduce : ('k, 'cmp) Base.Comparator.Module.t -> 'v Base.List.t -> get_key:('v -> 'k) @ local -> f:('v -> 'v -> 'v) -> ('k, 'v, 'cmp) Core.Map.t @@ portable

Like of_list_with_key; resolves duplicate keys the same way of_alist_fold does.

val is_empty : (_, _, _) Core.Map.t @ local -> Base.Bool.t @@ portable

Tests whether a map is empty or not.

val length : (_, _, _) Core.Map.t @ local -> Base.Int.t @@ portable

length map returns number of elements in map. O(1), but Tree.length is O(n).

val add : ('k, 'v, 'cmp) Core.Map.t -> key:'k -> data:'v -> ('k, 'v, 'cmp) Core.Map.t Base.Map.Or_duplicate.t @@ portable

add t ~key ~data adds a new entry to t mapping key to data and returns `Ok with the new map, or if key is already present in t, returns `Duplicate.

val add_exn : ('k, 'v, 'cmp) Core.Map.t -> key:'k -> data:'v -> ('k, 'v, 'cmp) Core.Map.t @@ portable

add_exn t ~key ~data adds a new entry to t mapping key to data and returns the new map, or if key is already present in t, raises.

val set : ('k, 'v, 'cmp) Core.Map.t -> key:'k -> data:'v -> ('k, 'v, 'cmp) Core.Map.t @@ portable

Returns a new map with the specified new binding; if the key was already bound, its previous binding disappears.

val add_multi : ('k, 'v Base.List.t, 'cmp) Core.Map.t -> key:'k -> data:'v -> ('k, 'v Base.List.t, 'cmp) Core.Map.t @@ portable

If key is not present then add a singleton list, otherwise, cons data onto the head of the existing list.

val remove_multi : ('k, 'v Base.List.t, 'cmp) Core.Map.t -> 'k -> ('k, 'v Base.List.t, 'cmp) Core.Map.t @@ portable

If k is present then remove its head element; if result is empty, remove the key.

val find_multi : ('k, 'v Base.List.t, 'cmp) Core.Map.t -> 'k -> 'v Base.List.t @@ portable

find_multi t key returns t's values for key if key is present in the table, and returns the empty list otherwise.

val change : ('k, 'v, 'cmp) Core.Map.t -> 'k -> f:('v Base.Option.t -> 'v Base.Option.t) @ local -> ('k, 'v, 'cmp) Core.Map.t @@ portable

change t key ~f returns a new map m that is the same as t on all keys except for key, and whose value for key is defined by f, i.e., find m key = f (find t key).

val update : ('k, 'v, 'cmp) Core.Map.t -> 'k -> f:('v Base.Option.t -> 'v) @ local -> ('k, 'v, 'cmp) Core.Map.t @@ portable

update t key ~f is change t key ~f:(fun o -> Some (f o)).

val update_and_return : ('k, 'v, 'cmp) Core.Map.t -> 'k -> f:('v Base.Option.t -> 'v) @ local -> 'v * ('k, 'v, 'cmp) Core.Map.t @@ portable

update_and_return t key ~f is like update t key ~f, but also returns the new value.

val find : ('k, 'v, 'cmp) Core.Map.t -> 'k -> 'v Base.Option.t @@ portable

Returns the value bound to the given key if it exists, and None otherwise.

val find_exn : ('k, 'v, 'cmp) Core.Map.t -> 'k -> 'v @@ portable

Returns the value bound to the given key, raising Caml.Not_found or Not_found_s if none exists.

Sourceval find_or_error : ('k, 'v, 'cmp) Core.Map.t -> 'k -> 'v Core.Or_error.t @@ portable
val remove : ('k, 'v, 'cmp) Core.Map.t -> 'k -> ('k, 'v, 'cmp) Core.Map.t @@ portable

Returns a new map with any binding for the key in question removed.

val mem : ('k, _, 'cmp) Core.Map.t -> 'k -> Base.Bool.t @@ portable

mem map key tests whether map contains a binding for key.

val iter_keys : ('k, _, _) Core.Map.t -> f:('k -> Base.Unit.t) @ local -> Base.Unit.t @@ portable

iter_keys t ~f calls f on every key in the map, going in order from the smallest to the largest keys.

val iter : (_, 'v, _) Core.Map.t -> f:('v -> Base.Unit.t) @ local -> Base.Unit.t @@ portable

iter t ~f calls f on every element in the map, going in order from the smallest to the largest keys.

val iteri : ('k, 'v, _) Core.Map.t -> f:(key:'k -> data:'v -> Base.Unit.t) @ local -> Base.Unit.t @@ portable

iteri t ~f calls f on every key and element in the map, going in order from the smallest to the largest keys.

module Continue_or_stop : sig ... end
module Finished_or_unfinished : sig ... end
val iteri_until : ('k, 'v, _) Core.Map.t -> f:(key:'k -> data:'v -> Core.Map.Continue_or_stop.t) @ local -> Core.Map.Finished_or_unfinished.t @@ portable

Iterates until f returns Stop. If f returns Stop, the final result is Unfinished. Otherwise, the final result is Finished.

Sourcemodule Merge_element : sig ... end
val iter2 : ('k, 'v1, 'cmp) Core.Map.t -> ('k, 'v2, 'cmp) Core.Map.t -> f:(key:'k -> data:('v1, 'v2) Core.Map.Merge_element.t -> Base.Unit.t) @ local -> Base.Unit.t @@ portable

Iterates two maps side by side. The complexity of this function is O(M+N). If two inputs are [(0, a); (1, a)] and [(1, b); (2, b)], f will be called with [(0, `Left a); (1, `Both (a, b)); (2, `Right b)]

val map : ('k, 'v1, 'cmp) Core.Map.t -> f:('v1 -> 'v2) @ local -> ('k, 'v2, 'cmp) Core.Map.t @@ portable

Returns new map with bound values replaced by the result of f applied to them.

val mapi : ('k, 'v1, 'cmp) Core.Map.t -> f:(key:'k -> data:'v1 -> 'v2) @ local -> ('k, 'v2, 'cmp) Core.Map.t @@ portable

Like map, but f takes both key and data as arguments.

val map_keys : ('k2, 'cmp2) Base.Comparator.Module.t -> ('k1, 'v, 'cmp1) Core.Map.t -> f:('k1 -> 'k2) @ local -> [ `Ok of ('k2, 'v, 'cmp2) Core.Map.t | `Duplicate_key of 'k2 ] @@ portable

Convert map with keys of type 'k1 to a map with keys of type 'k2 using f.

val map_keys_exn : ('k2, 'cmp2) Base.Comparator.Module.t -> ('k1, 'v, 'cmp1) Core.Map.t -> f:('k1 -> 'k2) @ local -> ('k2, 'v, 'cmp2) Core.Map.t @@ portable

Like map_keys, but raises on duplicate key.

val fold : ('k, 'v, _) Core.Map.t -> init:'a -> f:(key:'k -> data:'v -> 'a -> 'a) @ local -> 'a @@ portable

Folds over keys and data in map in increasing order of key.

val fold_until : ('k, 'v, _) Core.Map.t -> init:'acc -> f: (key:'k -> data:'v -> 'acc -> ('acc, 'final) Base.Container.Continue_or_stop.t) @ local -> finish:('acc -> 'final) @ local -> 'final @@ portable

Folds over keys and data in the map in increasing order of key, until the first time that f returns Stop _. If f returns Stop final, this function returns immediately with the value final. If f never returns Stop _, and the final call to f returns Continue last, this function returns finish last.

val fold_right : ('k, 'v, _) Core.Map.t -> init:'a -> f:(key:'k -> data:'v -> 'a -> 'a) @ local -> 'a @@ portable

Folds over keys and data in map in decreasing order of key.

val fold2 : ('k, 'v1, 'cmp) Core.Map.t -> ('k, 'v2, 'cmp) Core.Map.t -> init:'a -> f:(key:'k -> data:('v1, 'v2) Core.Map.Merge_element.t -> 'a -> 'a) @ local -> 'a @@ portable

Folds over two maps side by side, like iter2.

filter, filteri, filter_keys, filter_map, and filter_mapi run in O(n * lg n) time; they simply accumulate each key & data retained by f into a new map using add.

val filter_keys : ('k, 'v, 'cmp) Core.Map.t -> f:('k -> Base.Bool.t) @ local -> ('k, 'v, 'cmp) Core.Map.t @@ portable
val filter : ('k, 'v, 'cmp) Core.Map.t -> f:('v -> Base.Bool.t) @ local -> ('k, 'v, 'cmp) Core.Map.t @@ portable
val filteri : ('k, 'v, 'cmp) Core.Map.t -> f:(key:'k -> data:'v -> Base.Bool.t) @ local -> ('k, 'v, 'cmp) Core.Map.t @@ portable
val filter_map : ('k, 'v1, 'cmp) Core.Map.t -> f:('v1 -> 'v2 Base.Option.t) @ local -> ('k, 'v2, 'cmp) Core.Map.t @@ portable

Returns new map with bound values filtered by the result of f applied to them.

val filter_mapi : ('k, 'v1, 'cmp) Core.Map.t -> f:(key:'k -> data:'v1 -> 'v2 Base.Option.t) @ local -> ('k, 'v2, 'cmp) Core.Map.t @@ portable

Like filter_map, but function takes both key and data as arguments.

val partition_mapi : ('k, 'v1, 'cmp) Core.Map.t -> f:(key:'k -> data:'v1 -> ('v2, 'v3) Core.Either.t) @ local -> ('k, 'v2, 'cmp) Core.Map.t * ('k, 'v3, 'cmp) Core.Map.t @@ portable

partition_mapi t ~f returns two new ts, with each key in t appearing in exactly one of the result maps depending on its mapping in f.

val partition_map : ('k, 'v1, 'cmp) Core.Map.t -> f:('v1 -> ('v2, 'v3) Core.Either.t) @ local -> ('k, 'v2, 'cmp) Core.Map.t * ('k, 'v3, 'cmp) Core.Map.t @@ portable

partition_map t ~f = partition_mapi t ~f:(fun ~key:_ ~data -> f data)

val partition_result : ('k, ('ok, 'error) Core.Result.t, 'cmp) Core.Map.t -> ('k, 'ok, 'cmp) Core.Map.t * ('k, 'error, 'cmp) Core.Map.t @@ portable

partition_result t = partition_map t ~f:Result.to_either

val partitioni_tf : ('k, 'v, 'cmp) Core.Map.t -> f:(key:'k -> data:'v -> Base.Bool.t) @ local -> ('k, 'v, 'cmp) Core.Map.t * ('k, 'v, 'cmp) Core.Map.t @@ portable
  partitioni_tf t ~f
  = partition_mapi t ~f:(fun ~key ~data ->
    if f ~key ~data then First data else Second data)
val partition_tf : ('k, 'v, 'cmp) Core.Map.t -> f:('v -> Base.Bool.t) @ local -> ('k, 'v, 'cmp) Core.Map.t * ('k, 'v, 'cmp) Core.Map.t @@ portable

partition_tf t ~f = partitioni_tf t ~f:(fun ~key:_ ~data -> f data)

val combine_errors : ('k, 'v Core.Or_error.t, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.t Core.Or_error.t @@ portable

Produces Ok of a map including all keys if all data is Ok, or an Error including all errors otherwise.

val unzip : ('k, 'v1 * 'v2, 'cmp) Core.Map.t -> ('k, 'v1, 'cmp) Core.Map.t * ('k, 'v2, 'cmp) Core.Map.t @@ portable

Given a map of tuples, produces a tuple of maps. Equivalent to: map t ~f:fst, map t ~f:snd

val compare_direct : ('v -> 'v -> Base.Int.t) -> ('k, 'v, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.t -> Base.Int.t @@ portable

Total ordering between maps. The first argument is a total ordering used to compare data associated with equal keys in the two maps.

Sourceval hash_fold_direct : 'k Base.Hash.folder -> 'v Base.Hash.folder -> ('k, 'v, 'cmp) Core.Map.t Base.Hash.folder @@ portable

Hash function: a building block to use when hashing data structures containing maps in them. hash_fold_direct hash_fold_key is compatible with compare_direct iff hash_fold_key is compatible with (comparator m).compare of the map m being hashed.

val equal : ('v -> 'v -> Base.Bool.t) -> ('k, 'v, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.t -> Base.Bool.t @@ portable

equal cmp m1 m2 tests whether the maps m1 and m2 are equal, that is, contain equal keys and associate them with equal data. cmp is the equality predicate used to compare the data associated with the keys.

val keys : ('k, _, _) Core.Map.t -> 'k Base.List.t @@ portable

Returns list of keys in map in increasing order.

val data : (_, 'v, _) Core.Map.t -> 'v Base.List.t @@ portable

Returns list of data in map in increasing order of key.

val to_alist : ?key_order:[ `Increasing | `Decreasing ] -> ('k, 'v, _) Core.Map.t -> ('k * 'v) Base.List.t @@ portable

Creates association list from map.

  • parameter key_order

    default is `Increasing

Sourceval validate : name:('k -> Base.String.t) -> 'v Validate.check -> ('k, 'v, _) Core.Map.t Validate.check @@ portable
Sourceval validatei : name:('k -> Base.String.t) -> ('k * 'v) Validate.check -> ('k, 'v, _) Core.Map.t Validate.check @@ portable

Additional operations on maps

val merge : ('k, 'v1, 'cmp) Core.Map.t -> ('k, 'v2, 'cmp) Core.Map.t -> f: (key:'k -> ('v1, 'v2) Core.Map.Merge_element.t -> 'v3 Base.Option.t) @ local -> ('k, 'v3, 'cmp) Core.Map.t @@ portable

Merges two maps. The runtime is O(length(t1) + length(t2)).

The merge_* functions immediately below perform better in cases where they are applicable. For merging a list of maps especially, use merge_disjoin_exn or merge_skewed instead. If you don't require the full generality of ~f's behavior, use merge_by_case.

val merge_disjoint_exn : ('k, 'v, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.t @@ portable

Merges two dictionaries with the same type of data and disjoint sets of keys. Raises if any keys overlap.

Sourceval merge_skewed : ('k, 'v, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.t -> combine:(key:'k -> 'v -> 'v -> 'v) @ local -> ('k, 'v, 'cmp) Core.Map.t @@ portable

A special case of merge, merge_skewed t1 t2 is a map containing all the bindings of t1 and t2. Bindings that appear in both t1 and t2 are merged using the combine function. In a call combine ~key v1 v2 the value v1 comes from t1 and v2 from t2.

The runtime of merge_skewed is O(l1 * log(l2)), where l1 is the length of the smaller map and l2 the length of the larger map. This is likely to be faster than merge when one of the maps is a lot smaller, or when you merge a list of maps.

module When_unmatched : sig ... end
module When_matched : sig ... end
val merge_by_case : ('k, 'v1, 'cmp) Core.Map.t -> ('k, 'v2, 'cmp) Core.Map.t -> first:('k, 'v1, 'v3) Core.Map.When_unmatched.t @ local -> second:('k, 'v2, 'v3) Core.Map.When_unmatched.t @ local -> both:('k, 'v1, 'v2, 'v3) Core.Map.When_matched.t @ local -> ('k, 'v3, 'cmp) Core.Map.t @@ portable

An alternative to merge that is more efficient when unmatched keys are unconditionally dropped or kept unchanged in the result.

Sourcemodule Symmetric_diff_element : sig ... end
val symmetric_diff : ('k, 'v, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.t -> data_equal:('v -> 'v -> Base.Bool.t) -> ('k, 'v) Core.Map.Symmetric_diff_element.t Core.Sequence.t @@ portable

symmetric_diff t1 t2 ~data_equal returns a list of changes between t1 and t2. It is intended to be efficient in the case where t1 and t2 share a large amount of structure. In the case where t2 (resp. t1) is obtained by applying k additions and/or removals to t1 (resp. t2), this runs in min(O(k log n), O(n)), where n is length t1 + length t2. The keys in the output sequence will be in sorted order.

val fold_symmetric_diff : ('k, 'v, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.t -> data_equal:('v -> 'v -> Base.Bool.t) @ local -> init:'a -> f:('a -> ('k, 'v) Core.Map.Symmetric_diff_element.t -> 'a) @ local -> 'a @@ portable

fold_symmetric_diff t1 t2 ~data_equal folds across an implicit sequence of changes between t1 and t2, in sorted order by keys. Equivalent to Sequence.fold (symmetric_diff t1 t2 ~data_equal), and more efficient.

val min_elt : ('k, 'v, _) Core.Map.t -> ('k * 'v) Base.Option.t @@ portable

min_elt map returns Some (key, data) pair corresponding to the minimum key in map, None if map is empty.

val min_elt_exn : ('k, 'v, _) Core.Map.t -> 'k * 'v @@ portable
val max_elt : ('k, 'v, _) Core.Map.t -> ('k * 'v) Base.Option.t @@ portable

max_elt map returns Some (key, data) pair corresponding to the maximum key in map, and None if map is empty.

val max_elt_exn : ('k, 'v, _) Core.Map.t -> 'k * 'v @@ portable
val transpose_keys : ('k2, 'cmp2) Base.Comparator.Module.t -> ('k1, ('k2, 'v, 'cmp2) Core.Map.t, 'cmp1) Core.Map.t -> ('k2, ('k1, 'v, 'cmp1) Core.Map.t, 'cmp2) Core.Map.t @@ portable

Swap the inner and outer keys of nested maps. If transpose_keys m a = b, then find_exn (find_exn a i) j = find_exn (find_exn b j) i.

The following functions have the same semantics as similar functions in Core.List.

val for_all : (_, 'v, _) Core.Map.t -> f:('v -> Base.Bool.t) @ local -> Base.Bool.t @@ portable
val for_alli : ('k, 'v, _) Core.Map.t -> f:(key:'k -> data:'v -> Base.Bool.t) @ local -> Base.Bool.t @@ portable
val exists : (_, 'v, _) Core.Map.t -> f:('v -> Base.Bool.t) @ local -> Base.Bool.t @@ portable
val existsi : ('k, 'v, _) Core.Map.t -> f:(key:'k -> data:'v -> Base.Bool.t) @ local -> Base.Bool.t @@ portable
val count : (_, 'v, _) Core.Map.t -> f:('v -> Base.Bool.t) @ local -> Base.Int.t @@ portable
val counti : ('k, 'v, _) Core.Map.t -> f:(key:'k -> data:'v -> Base.Bool.t) @ local -> Base.Int.t @@ portable
val sum : (module Core.Container.Summable with type t = 'a) -> (_, 'v, _) Core.Map.t -> f:('v -> 'a) @ local -> 'a @@ portable
val sumi : (module Core.Container.Summable with type t = 'a) -> ('k, 'v, _) Core.Map.t -> f:(key:'k -> data:'v -> 'a) @ local -> 'a @@ portable
val split : ('k, 'v, 'cmp) Core.Map.t -> 'k -> ('k, 'v, 'cmp) Core.Map.t * ('k * 'v) Base.Option.t * ('k, 'v, 'cmp) Core.Map.t @@ portable

split t key returns a map of keys strictly less than key, the mapping of key if any, and a map of keys strictly greater than key.

Runtime is O(m + log n) where n is the size of the input map, and m is the size of the smaller of the two output maps. The O(m) term is due to the need to calculate the length of the output maps.

val split_le_gt : ('k, 'v, 'cmp) Core.Map.t -> 'k -> ('k, 'v, 'cmp) Core.Map.t * ('k, 'v, 'cmp) Core.Map.t @@ portable

split_le_gt t key returns a map of keys that are less or equal to key and a map of keys strictly greater than key.

Runtime is O(m + log n), where n is the size of the input map and m is the size of the smaller of the two output maps. The O(m) term is due to the need to calculate the length of the output maps.

val split_lt_ge : ('k, 'v, 'cmp) Core.Map.t -> 'k -> ('k, 'v, 'cmp) Core.Map.t * ('k, 'v, 'cmp) Core.Map.t @@ portable

split_lt_ge t key returns a map of keys strictly less than key and a map of keys that are greater or equal to key.

Runtime is O(m + log n), where n is the size of the input map and m is the size of the smaller of the two output maps. The O(m) term is due to the need to calculate the length of the output maps.

val count_lt : ('k, 'v, 'cmp) Core.Map.t -> 'k -> Base.Int.t @@ portable

count_lt t key returns the number of keys in t that are strictly less than key.

Runtime is O(log n) where n is the size of the input map.

val count_le : ('k, 'v, 'cmp) Core.Map.t -> 'k -> Base.Int.t @@ portable

count_le t key returns the number of keys in t that are less than or equal to key.

Runtime is O(log n) where n is the size of the input map.

val count_gt : ('k, 'v, 'cmp) Core.Map.t -> 'k -> Base.Int.t @@ portable

count_gt t key returns the number of keys in t that are strictly greater than key.

Runtime is O(log n) where n is the size of the input map.

val count_ge : ('k, 'v, 'cmp) Core.Map.t -> 'k -> Base.Int.t @@ portable

count_ge t key returns the number of keys in t that are greater than or equal to key.

Runtime is O(log n) where n is the size of the input map.

val append : lower_part:('k, 'v, 'cmp) Core.Map.t -> upper_part:('k, 'v, 'cmp) Core.Map.t -> [ `Ok of ('k, 'v, 'cmp) Core.Map.t | `Overlapping_key_ranges ] @@ portable

append ~lower_part ~upper_part returns `Ok map where map contains all the (key, value) pairs from the two input maps if all the keys from lower_part are less than all the keys from upper_part. Otherwise it returns `Overlapping_key_ranges.

Runtime is O(log n) where n is the size of the larger input map. This can be significantly faster than Map.merge or repeated Map.add.

  assert (
    match Map.append ~lower_part ~upper_part with
    | `Ok whole_map ->
      whole_map
      = Map.(of_alist_exn (List.append (to_alist lower_part) (to_alist upper_part)))
    | `Overlapping_key_ranges -> true)
val subrange : ('k, 'v, 'cmp) Core.Map.t -> lower_bound:'k Core.Maybe_bound.t -> upper_bound:'k Core.Maybe_bound.t -> ('k, 'v, 'cmp) Core.Map.t @@ portable

subrange t ~lower_bound ~upper_bound returns a map containing all the entries from t whose keys lie inside the interval indicated by ~lower_bound and ~upper_bound. If this interval is empty, an empty map is returned.

Runtime is O(log n) where n is the size of the input map.

val fold_range_inclusive : ('k, 'v, 'cmp) Core.Map.t -> min:'k -> max:'k -> init:'a -> f:(key:'k -> data:'v -> 'a -> 'a) @ local -> 'a @@ portable

fold_range_inclusive t ~min ~max ~init ~f folds f (with initial value ~init) over all keys (and their associated values) that are in the range [min, max] (inclusive).

val range_to_alist : ('k, 'v, 'cmp) Core.Map.t -> min:'k -> max:'k -> ('k * 'v) Base.List.t @@ portable

range_to_alist t ~min ~max returns an associative list of the elements whose keys lie in [min, max] (inclusive), with the smallest key being at the head of the list.

val closest_key : ('k, 'v, 'cmp) Core.Map.t -> [ `Greater_or_equal_to | `Greater_than | `Less_or_equal_to | `Less_than ] -> 'k -> ('k * 'v) Base.Option.t @@ portable

closest_key t dir k returns the (key, value) pair in t with key closest to k, which satisfies the given inequality bound.

For example, closest_key t `Less_than k would be the pair with the closest key to k where key < k.

to_sequence can be used to get the same results as closest_key. It is less efficient for individual lookups but more efficient for finding many elements starting at some value.

val nth : ('k, 'v, _) Core.Map.t -> Base.Int.t -> ('k * 'v) Base.Option.t @@ portable

nth t n finds the (key, value) pair of rank n (i.e., such that there are exactly n keys strictly less than the found key), if one exists. O(log(length t) + n) time.

val nth_exn : ('k, 'v, _) Core.Map.t -> Base.Int.t -> 'k * 'v @@ portable
val rank : ('k, 'v, 'cmp) Core.Map.t -> 'k -> Base.Int.t Base.Option.t @@ portable

rank t k if k is in t, returns the number of keys strictly less than k in t, otherwise None.

val split_n : ('k, 'v, 'cmp) Core.Map.t -> Base.Int.t -> ('k, 'v, 'cmp) Core.Map.t * ('k, 'v, 'cmp) Core.Map.t @@ portable

split_n t n = l, r such that append ~lower_part:l ~upper_part:r = `Ok t and length l = n, or as close as possible if n < 0 or n > length t.

val to_sequence : ?order:[ `Increasing_key | `Decreasing_key ] -> ?keys_greater_or_equal_to:'k -> ?keys_less_or_equal_to:'k -> ('k, 'v, 'cmp) Core.Map.t -> ('k * 'v) Core.Sequence.t @@ portable

to_sequence ?order ?keys_greater_or_equal_to ?keys_less_or_equal_to t gives a sequence of key-value pairs between keys_less_or_equal_to and keys_greater_or_equal_to inclusive, presented in order. If keys_greater_or_equal_to > keys_less_or_equal_to, the sequence is empty. Cost is O(log n) up front and amortized O(1) to produce each element.

  • parameter order

    `Increasing_key is the default

binary_search t ~compare which elt returns the (key, value) pair in t specified by compare and which, if one exists.

t must be sorted in increasing order according to compare, where compare and elt divide t into three (possibly empty) segments:

  |  < elt  |  = elt  |  > elt  |

binary_search returns an element on the boundary of segments as specified by which. See the diagram below next to the which variants.

binary_search does not check that compare orders t, and behavior is unspecified if compare doesn't order t. Behavior is also unspecified if compare mutates t.

val binary_search_segmented : ('k, 'v, 'cmp) Core.Map.t -> segment_of:(key:'k -> data:'v -> [ `Left | `Right ]) @ local -> [ `Last_on_left | `First_on_right ] -> ('k * 'v) Base.Option.t @@ portable

binary_search_segmented t ~segment_of which takes a segment_of function that divides t into two (possibly empty) segments:

  | segment_of elt = `Left | segment_of elt = `Right |

binary_search_segmented returns the (key, value) pair on the boundary of the segments as specified by which: `Last_on_left yields the last element of the left segment, while `First_on_right yields the first element of the right segment. It returns None if the segment is empty.

binary_search_segmented does not check that segment_of segments t as in the diagram, and behavior is unspecified if segment_of doesn't segment t. Behavior is also unspecified if segment_of mutates t.

val binary_search_subrange : ('k, 'v, 'cmp) Core.Map.t -> compare:(key:'k -> data:'v -> 'bound -> Base.Int.t) @ local -> lower_bound:'bound Core.Maybe_bound.t -> upper_bound:'bound Core.Maybe_bound.t -> ('k, 'v, 'cmp) Core.Map.t @@ portable

binary_search_subrange takes a compare function that divides t into three (possibly empty) segments with respect to lower_bound and upper_bound:

  | Below_lower_bound | In_range | Above_upper_bound |

and returns a map of the key-value pairs in range.

Runtime is O(log n + m) where n is the length of the input map and m is the length of the output. The linear term is to compute the length of the output.

Behavior is undefined if compare does not segment t as shown above, or is compare mutates its inputs.

Sourcemodule Make_applicative_traversals (A : sig ... end) : sig ... end

Creates traversals to reconstruct a map within an applicative. Uses Lazy_applicative so that the map can be traversed within the applicative, rather than needing to be traversed all at once, outside the applicative.

Sourceval of_key_set : ('key, 'cmp) Base.Set.t -> f:('key -> 'data) @ local -> ('key, 'data, 'cmp) Core.Map.t @@ portable

Convert a set to a map. Runs in O(length t) time plus a call to f for each key to compute the associated data.

Sourceval key_set : ('key, _, 'cmp) Core.Map.t -> ('key, 'cmp) Base.Set.t @@ portable

Converts a map to a set of its keys. Runs in O(length t) time.

Sourceval quickcheck_generator : ('k, 'cmp) Base.Comparator.Module.t -> 'k Core.Quickcheck.Generator.t -> 'v Core.Quickcheck.Generator.t -> ('k, 'v, 'cmp) Core.Map.t Core.Quickcheck.Generator.t @@ portable
Sourceval quickcheck_observer : 'k Core.Quickcheck.Observer.t -> 'v Core.Quickcheck.Observer.t -> ('k, 'v, 'cmp) Core.Map.t Core.Quickcheck.Observer.t @@ portable
Sourceval quickcheck_shrinker : 'k Core.Quickcheck.Shrinker.t -> 'v Core.Quickcheck.Shrinker.t -> ('k, 'v, 'cmp) Core.Map.t Core.Quickcheck.Shrinker.t @@ portable

This shrinker and the other shrinkers for maps and trees produce a shrunk value by dropping a key-value pair, shrinking a key or shrinking a value. A shrunk key will override an existing key's value.

Which Map module should you use?

The map types and operations appear in three places:

where Key is any module defining values that can be used as keys of a map, like Int, String, etc. To add this functionality to an arbitrary module, use the Comparable.Make functor.

You should use Map for functions that access existing maps, like find, mem, add, fold, iter, and to_alist. For functions that create maps, like empty, singleton, and of_alist, strive to use the corresponding Key.Map function, which will use the comparison function specifically for Key. As a last resort, if you don't have easy access to a comparison function for the keys in your map, use Map.Poly to create the map. This will use OCaml's built-in polymorphic comparison to compare keys, with all the usual performance and robustness problems that entails.

Interface design details

An instance of the map type is determined by the types of the map's keys and values, and the comparison function used to order the keys:

  type ('key, 'value, 'cmp) Map.t

'cmp is a phantom type uniquely identifying the comparison function, as generated by Comparator.Make.

Map.Poly supports arbitrary key and value types, but enforces that the comparison function used to order the keys is polymorphic comparison. Key.Map has a fixed key type and comparison function, and supports arbitrary values.

  type ('key, 'value) Map.Poly.t = ('key , 'value, Comparator.Poly.t     ) Map.t
  type 'value Key.Map.t          = (Key.t, 'value, Key.comparator_witness) Map.t

The same map operations exist in Map, Map.Poly, and Key.Map, albeit with different types. For example:

  val Map.length      : (_, _, _) Map.t   -> int
  val Map.Poly.length : (_, _) Map.Poly.t -> int
  val Key.Map.length  : _ Key.Map.t       -> int

Because Map.Poly.t and Key.Map.t are exposed as instances of the more general Map.t type, one can use Map.length on any map. The same is true for all of the functions that access an existing map, such as add, change, find, fold, iter, map, to_alist, etc.

Depending on the number of type variables N, the type of accessor (resp. creator) functions is defined in the module type AccessorsN (CreatorsN) in Map_intf. Also for creators, when the comparison function is not fixed, i.e., the 'cmp variable of Map.t is free, we need to pass a comparator to the function creating the map. The module type is called Creators3_with_comparator. There is also a module type Accessors3_with_comparator in addition to Accessors3 which used for trees since the comparator is not known.

Sourcemodule Using_comparator : sig ... end
Sourcemodule Poly : sig ... end
include sig ... end
Sourcemodule type Key_plain = Core.Map_intf.Key_plain
Sourcemodule type Key = Core.Map_intf.Key
Sourcemodule type Key_binable = Core.Map_intf.Key_binable
Sourcemodule type Key_hashable = Core.Map_intf.Key_hashable
Sourcemodule type Key_binable_hashable = Core.Map_intf.Key_binable_hashable
include sig ... end
Sourcemodule type S_plain = Core.Map_intf.S_plain
Sourcemodule type S = Core.Map_intf.S
Sourcemodule type S_binable = Core.Map_intf.S_binable
Sourcemodule Make_plain (Key : sig ... end) : sig ... end
Sourcemodule Make_plain_using_comparator (Key : sig ... end) : sig ... end
Sourcemodule Provide_of_sexp (Key : sig ... end) : sig ... end
Sourcemodule Make (Key : sig ... end) : sig ... end
Sourcemodule Make_using_comparator (Key : sig ... end) : sig ... end
Sourcemodule Key_bin_io = Core.Map_intf.Key_bin_io
Sourcemodule Provide_bin_io (Key : sig ... end) : sig ... end
Sourcemodule Make_binable (Key : sig ... end) : sig ... end
Sourcemodule Make_binable_using_comparator (Key : sig ... end) : sig ... end
Sourcemodule Provide_stable_witness (Key : sig ... end) : sig ... end
Sourcemodule Provide_hash (Key : sig ... end) : sig ... end
include Core.Map_intf.For_deriving with type ('a, 'b, 'c) t := ('a, 'b, 'c) Core.Map.t
include Base.Map.For_deriving with type ('a, 'b, 'c) t := ('a, 'b, 'c) Core.Map.t
module type Sexp_of_m = Base.Sexpable.Sexp_of
module type M_of_sexp = sig ... end
module type M_sexp_grammar = sig ... end
module type Compare_m = sig ... end
module type Equal_m = sig ... end
module type Hash_fold_m = Base.Hasher.S
module type Globalize_m = sig ... end
val sexp_of_m__t : (module Core.Map.Sexp_of_m with type t = 'k) -> ('v -> Sexplib0.Sexp.t) -> ('k, 'v, 'cmp) Core.Map.t -> Sexplib0.Sexp.t
val m__t_of_sexp : (module Core.Map.M_of_sexp with type comparator_witness = 'cmp and type t = 'k) -> (Sexplib0.Sexp.t -> 'v) -> Sexplib0.Sexp.t -> ('k, 'v, 'cmp) Core.Map.t
val m__t_sexp_grammar : (module Core.Map.M_sexp_grammar with type t = 'k) -> 'v Sexplib0.Sexp_grammar.t -> ('k, 'v, 'cmp) Core.Map.t Sexplib0.Sexp_grammar.t @@ portable
val compare_m__t : (module Core.Map.Compare_m) -> ('v -> 'v -> int) -> ('k, 'v, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.t -> int
val compare_m__t__local : (module Core.Map.Compare_m) -> ('v @ local -> 'v @ local -> int) -> ('k, 'v, 'cmp) Core.Map.t @ local -> ('k, 'v, 'cmp) Core.Map.t @ local -> int
val equal_m__t : (module Core.Map.Equal_m) -> ('v -> 'v -> bool) -> ('k, 'v, 'cmp) Core.Map.t -> ('k, 'v, 'cmp) Core.Map.t -> bool
val equal_m__t__local : (module Core.Map.Equal_m) -> ('v @ local -> 'v @ local -> bool) -> ('k, 'v, 'cmp) Core.Map.t @ local -> ('k, 'v, 'cmp) Core.Map.t @ local -> bool
val globalize_m__t : (module Core.Map.Globalize_m) -> _ -> ('k, 'v, 'cmp) Core.Map.t @ local -> ('k, 'v, 'cmp) Core.Map.t
module M = Base.Map.M

The following *bin* functions support bin-io on base-style maps, e.g.:

  type t = int Map.M(String).t [@@deriving bin_io]
Sourceval __bin_read_m__t__ : ('a, 'c) Core.Map_intf.Key_bin_io.t -> 'b Bin_prot.Read.reader -> ('a, 'b, 'c) Core.Map.t Bin_prot.Read.vtag_reader

The following quickcheck* functions support deriving quickcheck on base-style maps, e.g.:

  type t = int Map.M(String).t [@@deriving quickcheck]
Sourcemodule type Quickcheck_generator_m = sig ... end
Sourcemodule type Quickcheck_observer_m = sig ... end
Sourcemodule type Quickcheck_shrinker_m = sig ... end
Sourcemodule Make_tree_plain (Key : sig ... end) : sig ... end
Sourcemodule Make_tree (Key : sig ... end) : sig ... end
Sourcemodule Stable : sig ... end

The following functors may be used to define stable modules