Module Core_kernel.Map
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
let compare x y = Tuple2.compare Int.compare Int.compare
let sexp_of_t = Tuple2.sexp_of_t Int.sexp_of_t Int.sexp_of_t
end
include T
include Comparable.Make(T)
endThis 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. It's yet nicer to do this with the appropriate PPXs:
module Foo = struct
module T =
struct type t = int * int [@@deriving sexp_of, compare] end
include T
include Comparable.Make(T)
endThe interface
type ('key, +'value, 'cmp) t= ('key, 'value, 'cmp) Base.Map.ttype ('k, 'cmp) comparator= (module Comparator.S with type comparator_witness = 'cmp and type t = 'k)
val invariants : (_, _, _) t -> Core_kernel__.Import.boolTest if invariants of internal AVL search tree hold.
val comparator : ('a, _, 'cmp) t -> ('a, 'cmp) Comparator.tval comparator_s : ('a, _, 'cmp) t -> ('a, 'cmp) comparatorval empty : ('a, 'cmp) comparator -> ('a, 'b, 'cmp) tThe empty map.
val singleton : ('a, 'cmp) comparator -> 'a -> 'b -> ('a, 'b, 'cmp) tMap with one (key, data) pair.
val of_alist : ('a, 'cmp) comparator -> ('a * 'b) Core_kernel__.Import.list -> [ `Ok of ('a, 'b, 'cmp) t | `Duplicate_key of 'a ]Creates map from an association list with unique keys.
val of_alist_or_error : ('a, 'cmp) comparator -> ('a * 'b) Core_kernel__.Import.list -> ('a, 'b, 'cmp) t Or_error.tCreates map from an association list with unique keys. Returns an error if duplicate
'akeys are found.
val of_alist_exn : ('a, 'cmp) comparator -> ('a * 'b) Core_kernel__.Import.list -> ('a, 'b, 'cmp) tCreates map from an association list with unique keys. Raises an exception if duplicate
'akeys are found.
val of_hashtbl_exn : ('a, 'cmp) comparator -> ('a, 'b) Hashtbl.t -> ('a, 'b, 'cmp) tof_hashtbl_exncreates a map from bindings present in a hash table.of_hashtbl_exnraises if there are distinct keysa1anda2in the table withcomparator.compare a1 a2 = 0, which is only possible if the hash-table comparison function is different thancomparator.compare. In the common case, the comparison is the same, in which caseof_hashtbl_exndoes not raise, regardless of the keys present in the table.
val of_alist_multi : ('a, 'cmp) comparator -> ('a * 'b) Core_kernel__.Import.list -> ('a, 'b Core_kernel__.Import.list, 'cmp) tCreates map from an association list with possibly repeated keys.
val of_alist_fold : ('a, 'cmp) comparator -> ('a * 'b) Core_kernel__.Import.list -> init:'c -> f:('c -> 'b -> 'c) -> ('a, 'c, 'cmp) tCombines an association list into a map, folding together bound values with common keys.
val of_alist_reduce : ('a, 'cmp) comparator -> ('a * 'b) Core_kernel__.Import.list -> f:('b -> 'b -> 'b) -> ('a, 'b, 'cmp) tCombines an association list into a map, reducing together bound values with common keys.
val of_iteri : ('a, 'cmp) comparator -> iteri:(f:(key:'a -> data:'b -> Core_kernel__.Import.unit) -> Core_kernel__.Import.unit) -> [ `Ok of ('a, 'b, 'cmp) t | `Duplicate_key of 'a ]of_iteri ~iteribehaves likeof_alist, except that instead of taking a concrete datastruture, it takes an iteration function. For instance, to convert a string table into a map:of_iteri (module String) ~f:(Hashtbl.iteri table). It is faster than adding the elements one by one.
Trees
Parallel to the three kinds of map modules Map, Map.Poly, and Key.Map, there are also tree modules Map.Tree, Map.Poly.Tree, and Key.Map.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 and Key.Map.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).
module Tree : sig ... endval to_tree : ('k, 'v, 'cmp) t -> ('k, 'v, 'cmp) Tree.tval of_tree : ('k, 'cmp) comparator -> ('k, 'v, 'cmp) Tree.t -> ('k, 'v, 'cmp) tCreates a
tfrom aTree.tand aComparator.t. This is an O(n) operation as it must discover the length of theTree.t.
More interface
val of_sorted_array : ('a, 'cmp) comparator -> ('a * 'b) Core_kernel__.Import.array -> ('a, 'b, 'cmp) t Or_error.tCreates 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) comparator -> ('a * 'b) Core_kernel__.Import.array -> ('a, 'b, 'cmp) tLike
of_sorted_arrayexcept it returns a map with broken invariants when anErrorwould have been returned.
val of_increasing_iterator_unchecked : ('a, 'cmp) comparator -> len:Core_kernel__.Import.int -> f:(Core_kernel__.Import.int -> 'a * 'b) -> ('a, 'b, 'cmp) tof_increasing_iterator_unchecked c ~len ~fbehaves likeof_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.fwill be called with 0, 1, ...len - 1, in order.
val of_increasing_sequence : ('k, 'cmp) comparator -> ('k * 'v) Sequence.t -> ('k, 'v, 'cmp) t Or_error.tof_increasing_sequence c seqbehaves likeof_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) comparator -> ('k * 'v) Sequence.t -> [ `Ok of ('k, 'v, 'cmp) t | `Duplicate_key of 'k ]Creates a map from an association sequence with unique keys.
of_sequence c seqbehaves likeof_alist c (Sequence.to_list seq)but does not allocate the intermediate list.If your sequence is increasing, use
of_increasing_sequencefor better performance.
val of_sequence_or_error : ('a, 'cmp) comparator -> ('a * 'b) Sequence.t -> ('a, 'b, 'cmp) t Or_error.tCreates a map from an association sequence with unique keys, returning an error if duplicate
'akeys are found.of_sequence_or_error c seqbehaves likeof_alist_or_error c (Sequence.to_list seq)but does not allocate the intermediate list.
val of_sequence_exn : ('a, 'cmp) comparator -> ('a * 'b) Sequence.t -> ('a, 'b, 'cmp) tCreates a map from an association sequence with unique keys, raising an exception if duplicate
'akeys are found.of_sequence_exn c seqbehaves likeof_alist_exn c (Sequence.to_list seq)but does not allocate the intermediate list.
val of_sequence_multi : ('a, 'cmp) comparator -> ('a * 'b) Sequence.t -> ('a, 'b Core_kernel__.Import.list, 'cmp) tCreates 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 seqbehaves likeof_alist_multi c (Sequence.to_list seq)but does not allocate the intermediate list.
val of_sequence_fold : ('a, 'cmp) comparator -> ('a * 'b) Sequence.t -> init:'c -> f:('c -> 'b -> 'c) -> ('a, 'c, 'cmp) tCombines an association sequence into a map, folding together bound values with common keys.
of_sequence_fold c seq ~init ~fbehaves likeof_alist_fold c (Sequence.to_list seq) ~init ~fbut does not allocate the intermediate list.
val of_sequence_reduce : ('a, 'cmp) comparator -> ('a * 'b) Sequence.t -> f:('b -> 'b -> 'b) -> ('a, 'b, 'cmp) tCombines an association sequence into a map, reducing together bound values with common keys.
of_sequence_reduce c seq ~fbehaves likeof_alist_reduce c (Sequence.to_list seq) ~fbut does not allocate the intermediate list.
val is_empty : (_, _, _) t -> Core_kernel__.Import.boolTests whether a map is empty or not.
val length : (_, _, _) t -> Core_kernel__.Import.intlength mapreturns number of elements inmap. O(1), butTree.lengthis O(n).
val add : ('k, 'v, 'cmp) t -> key:'k -> data:'v -> ('k, 'v, 'cmp) t Map_intf.Or_duplicate.tadd_exn t ~key ~datareturnstextended withkeymapped todata, raising ifmem key t.
val add_exn : ('k, 'v, 'cmp) t -> key:'k -> data:'v -> ('k, 'v, 'cmp) tval set : ('k, 'v, 'cmp) t -> key:'k -> data:'v -> ('k, 'v, 'cmp) tReturns a new map with the specified new binding; if the key was already bound, its previous binding disappears.
val add_multi : ('k, 'v Core_kernel__.Import.list, 'cmp) t -> key:'k -> data:'v -> ('k, 'v Core_kernel__.Import.list, 'cmp) tIf
keyis not present then add a singleton list, otherwise, cons data onto the head of the existing list.
val remove_multi : ('k, 'v Core_kernel__.Import.list, 'cmp) t -> 'k -> ('k, 'v Core_kernel__.Import.list, 'cmp) tIf
kis present then remove its head element; if result is empty, remove the key.
val find_multi : ('k, 'v Core_kernel__.Import.list, 'cmp) t -> 'k -> 'v Core_kernel__.Import.listfind_multi t keyreturnst's values forkeyifkeyis present in the table, and returns the empty list otherwise.
val change : ('k, 'v, 'cmp) t -> 'k -> f:('v Core_kernel__.Import.option -> 'v Core_kernel__.Import.option) -> ('k, 'v, 'cmp) tchange t key ~freturns a new mapmthat is the same aston all keys except forkey, and whose value forkeyis defined byf, i.e.,find m key = f (find t key).
val update : ('k, 'v, 'cmp) t -> 'k -> f:('v Core_kernel__.Import.option -> 'v) -> ('k, 'v, 'cmp) tupdate t key ~fischange t key ~f:(fun o -> Some (f o)).
val find : ('k, 'v, 'cmp) t -> 'k -> 'v Core_kernel__.Import.optionReturns the value bound to the given key if it exists, and
Noneotherwise.
val find_exn : ('k, 'v, 'cmp) t -> 'k -> 'vReturns the value bound to the given key, raising
Caml.Not_foundorNot_found_sif none exists.
val find_or_error : ('k, 'v, 'cmp) t -> 'k -> 'v Or_error.tval remove : ('k, 'v, 'cmp) t -> 'k -> ('k, 'v, 'cmp) tReturns a new map with any binding for the key in question removed.
val mem : ('k, _, 'cmp) t -> 'k -> Core_kernel__.Import.boolmem map keytests whethermapcontains a binding forkey.
val iter_keys : ('k, _, _) t -> f:('k -> Core_kernel__.Import.unit) -> Core_kernel__.Import.unitval iter : (_, 'v, _) t -> f:('v -> Core_kernel__.Import.unit) -> Core_kernel__.Import.unitval iteri : ('k, 'v, _) t -> f:(key:'k -> data:'v -> Core_kernel__.Import.unit) -> Core_kernel__.Import.unit
module Continue_or_stop : sig ... endmodule Finished_or_unfinished : sig ... endval iteri_until : ('k, 'v, _) t -> f:(key:'k -> data:'v -> Continue_or_stop.t) -> Finished_or_unfinished.tIterates until
freturnsStop. IffreturnsStop, the final result isUnfinished. Otherwise, the final result isFinished.
val iter2 : ('k, 'v1, 'cmp) t -> ('k, 'v2, 'cmp) t -> f:(key:'k -> data:[ `Left of 'v1 | `Right of 'v2 | `Both of 'v1 * 'v2 ] -> Core_kernel__.Import.unit) -> Core_kernel__.Import.unitIterates 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)],fwill be called with[(0, `Left a); (1, `Both (a, b)); (2, `Right b)]
val map : ('k, 'v1, 'cmp) t -> f:('v1 -> 'v2) -> ('k, 'v2, 'cmp) tReturns new map with bound values replaced by the result of
fapplied to them.
val mapi : ('k, 'v1, 'cmp) t -> f:(key:'k -> data:'v1 -> 'v2) -> ('k, 'v2, 'cmp) tLike
map, butftakes both key and data as arguments.
val fold : ('k, 'v, _) t -> init:'a -> f:(key:'k -> data:'v -> 'a -> 'a) -> 'aFolds over keys and data in map in increasing order of key.
val fold_right : ('k, 'v, _) t -> init:'a -> f:(key:'k -> data:'v -> 'a -> 'a) -> 'aFolds over keys and data in map in decreasing order of key.
val fold2 : ('k, 'v1, 'cmp) t -> ('k, 'v2, 'cmp) t -> init:'a -> f:(key:'k -> data:[ `Left of 'v1 | `Right of 'v2 | `Both of 'v1 * 'v2 ] -> 'a -> 'a) -> 'aFolds over two maps side by side, like
iter2.
val filter_keys : ('k, 'v, 'cmp) t -> f:('k -> Core_kernel__.Import.bool) -> ('k, 'v, 'cmp) tval filter : ('k, 'v, 'cmp) t -> f:('v -> Core_kernel__.Import.bool) -> ('k, 'v, 'cmp) tval filteri : ('k, 'v, 'cmp) t -> f:(key:'k -> data:'v -> Core_kernel__.Import.bool) -> ('k, 'v, 'cmp) tval filter_map : ('k, 'v1, 'cmp) t -> f:('v1 -> 'v2 Core_kernel__.Import.option) -> ('k, 'v2, 'cmp) tReturns new map with bound values filtered by the result of
fapplied to them.
val filter_mapi : ('k, 'v1, 'cmp) t -> f:(key:'k -> data:'v1 -> 'v2 Core_kernel__.Import.option) -> ('k, 'v2, 'cmp) tLike
filter_map, but function takes both key and data as arguments.
val partition_mapi : ('k, 'v1, 'cmp) t -> f:(key:'k -> data:'v1 -> ('v2, 'v3) Either.t) -> ('k, 'v2, 'cmp) t * ('k, 'v3, 'cmp) tpartition_mapi t ~freturns two newts, with each key intappearing in exactly one of the result maps depending on its mapping inf.
val partition_map : ('k, 'v1, 'cmp) t -> f:('v1 -> ('v2, 'v3) Either.t) -> ('k, 'v2, 'cmp) t * ('k, 'v3, 'cmp) tpartition_map t ~f = partition_mapi t ~f:(fun ~key:_ ~data -> f data)
val partitioni_tf : ('k, 'v, 'cmp) t -> f:(key:'k -> data:'v -> Core_kernel__.Import.bool) -> ('k, 'v, 'cmp) t * ('k, 'v, 'cmp) tpartitioni_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) t -> f:('v -> Core_kernel__.Import.bool) -> ('k, 'v, 'cmp) t * ('k, 'v, 'cmp) tpartition_tf t ~f = partitioni_tf t ~f:(fun ~key:_ ~data -> f data)
val combine_errors : ('k, 'v Or_error.t, 'cmp) t -> ('k, 'v, 'cmp) t Or_error.tProduces
Okof a map including all keys if all data isOk, or anErrorincluding all errors otherwise.
val compare_direct : ('v -> 'v -> Core_kernel__.Import.int) -> ('k, 'v, 'cmp) t -> ('k, 'v, 'cmp) t -> Core_kernel__.Import.intTotal ordering between maps. The first argument is a total ordering used to compare data associated with equal keys in the two maps.
val hash_fold_direct : 'k Core_kernel__.Import.Hash.folder -> 'v Core_kernel__.Import.Hash.folder -> ('k, 'v, 'cmp) t Core_kernel__.Import.Hash.folderHash function: a building block to use when hashing data structures containing maps in them.
hash_fold_direct hash_fold_keyis compatible withcompare_directiffhash_fold_keyis compatible with(comparator m).compareof the mapmbeing hashed.
val equal : ('v -> 'v -> Core_kernel__.Import.bool) -> ('k, 'v, 'cmp) t -> ('k, 'v, 'cmp) t -> Core_kernel__.Import.boolequal cmp m1 m2tests whether the mapsm1andm2are equal, that is, contain equal keys and associate them with equal data.cmpis the equality predicate used to compare the data associated with the keys.
val keys : ('k, _, _) t -> 'k Core_kernel__.Import.listReturns list of keys in map.
val data : (_, 'v, _) t -> 'v Core_kernel__.Import.listReturns list of data in map.
val to_alist : ?key_order:[ `Increasing | `Decreasing ] -> ('k, 'v, _) t -> ('k * 'v) Core_kernel__.Import.listCreates association list from map.
- parameter key_order
default is
`Increasing
val validate : name:('k -> Core_kernel__.Import.string) -> 'v Core_kernel__.Import.Validate.check -> ('k, 'v, _) t Core_kernel__.Import.Validate.checkval validatei : name:('k -> Core_kernel__.Import.string) -> ('k * 'v) Core_kernel__.Import.Validate.check -> ('k, 'v, _) t Core_kernel__.Import.Validate.check
Additional operations on maps
val merge : ('k, 'v1, 'cmp) t -> ('k, 'v2, 'cmp) t -> f:(key:'k -> [ `Left of 'v1 | `Right of 'v2 | `Both of 'v1 * 'v2 ] -> 'v3 Core_kernel__.Import.option) -> ('k, 'v3, 'cmp) tMerges two maps. The runtime is O(length(t1) + length(t2)). In particular, you shouldn't use this function to merge a list of maps. Consider using
merge_skewedinstead.
val merge_skewed : ('k, 'v, 'cmp) t -> ('k, 'v, 'cmp) t -> combine:(key:'k -> 'v -> 'v -> 'v) -> ('k, 'v, 'cmp) tA special case of
merge,merge_skewed t1 t2is a map containing all the bindings oft1andt2. Bindings that appear in botht1andt2are merged using thecombinefunction. In a callcombine ~key v1 v2the valuev1comes fromt1andv2fromt2.The runtime of
merge_skewedisO(l1 * log(l2)), wherel1is the length of the smaller map andl2the length of the larger map. This is likely to be faster thanmergewhen one of the maps is a lot smaller, or when you merge a list of maps.
module Symmetric_diff_element : sig ... endval symmetric_diff : ('k, 'v, 'cmp) t -> ('k, 'v, 'cmp) t -> data_equal:('v -> 'v -> Core_kernel__.Import.bool) -> ('k, 'v) Symmetric_diff_element.t Sequence.tsymmetric_diff t1 t2 ~data_equalreturns a list of changes betweent1andt2. It is intended to be efficient in the case wheret1andt2share a large amount of structure. The keys in the output sequence will be in sorted order.
val fold_symmetric_diff : ('k, 'v, 'cmp) t -> ('k, 'v, 'cmp) t -> data_equal:('v -> 'v -> Core_kernel__.Import.bool) -> init:'a -> f:('a -> ('k, 'v) Symmetric_diff_element.t -> 'a) -> 'afold_symmetric_diff t1 t2 ~data_equalfolds across an implicit sequence of changes betweent1andt2, in sorted order by keys. Equivalent toSequence.fold (symmetric_diff t1 t2 ~data_equal), and more efficient.
val min_elt : ('k, 'v, _) t -> ('k * 'v) Core_kernel__.Import.optionmin_elt mapreturnsSome (key, data)pair corresponding to the minimum key inmap,Noneifmapis empty.
val min_elt_exn : ('k, 'v, _) t -> 'k * 'vval max_elt : ('k, 'v, _) t -> ('k * 'v) Core_kernel__.Import.optionmax_elt mapreturnsSome (key, data)pair corresponding to the maximum key inmap, andNoneifmapis empty.
val max_elt_exn : ('k, 'v, _) t -> 'k * 'v
val for_all : ('k, 'v, _) t -> f:('v -> Core_kernel__.Import.bool) -> Core_kernel__.Import.boolval for_alli : ('k, 'v, _) t -> f:(key:'k -> data:'v -> Core_kernel__.Import.bool) -> Core_kernel__.Import.boolval exists : ('k, 'v, _) t -> f:('v -> Core_kernel__.Import.bool) -> Core_kernel__.Import.boolval existsi : ('k, 'v, _) t -> f:(key:'k -> data:'v -> Core_kernel__.Import.bool) -> Core_kernel__.Import.boolval count : ('k, 'v, _) t -> f:('v -> Core_kernel__.Import.bool) -> Core_kernel__.Import.intval counti : ('k, 'v, _) t -> f:(key:'k -> data:'v -> Core_kernel__.Import.bool) -> Core_kernel__.Import.intval split : ('k, 'v, 'cmp) t -> 'k -> ('k, 'v, 'cmp) t * ('k * 'v) Core_kernel__.Import.option * ('k, 'v, 'cmp) tsplit t keyreturns a map of keys strictly less thankey, the mapping ofkeyif any, and a map of keys strictly greater thankey.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 append : lower_part:('k, 'v, 'cmp) t -> upper_part:('k, 'v, 'cmp) t -> [ `Ok of ('k, 'v, 'cmp) t | `Overlapping_key_ranges ]append ~lower_part ~upper_partreturns`Ok mapwheremapcontains all the(key, value)pairs from the two input maps if all the keys fromlower_partare less than all the keys fromupper_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.mergeor repeatedMap.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) t -> lower_bound:'k Maybe_bound.t -> upper_bound:'k Maybe_bound.t -> ('k, 'v, 'cmp) tsubrange t ~lower_bound ~upper_boundreturns a map containing all the entries fromtwhose keys lie inside the interval indicated by~lower_boundand~upper_bound. If this interval is empty, an empty map is returned.Runtime is O(m + log n) where n is the size of the input map, and m is the size of the output map. The O(m) term is due to the need to calculate the length of the output map.
val fold_range_inclusive : ('k, 'v, 'cmp) t -> min:'k -> max:'k -> init:'a -> f:(key:'k -> data:'v -> 'a -> 'a) -> 'afold_range_inclusive t ~min ~max ~init ~ffoldsf(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) t -> min:'k -> max:'k -> ('k * 'v) Core_kernel__.Import.listrange_to_alist t ~min ~maxreturns 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) t -> [ `Greater_or_equal_to | `Greater_than | `Less_or_equal_to | `Less_than ] -> 'k -> ('k * 'v) Core_kernel__.Import.optionclosest_key t dir kreturns the(key, value)pair intwithkeyclosest tok, which satisfies the given inequality bound.For example,
closest_key t `Less_than kwould be the pair with the closest key tokwherekey < k.to_sequencecan be used to get the same results asclosest_key. It is less efficient for individual lookups but more efficient for finding many elements starting at some value.
val nth : ('k, 'v, _) t -> Core_kernel__.Import.int -> ('k * 'v) Core_kernel__.Import.optionnth t nfinds 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, _) t -> Core_kernel__.Import.int -> 'k * 'vval rank : ('k, 'v, 'cmp) t -> 'k -> Core_kernel__.Import.int Core_kernel__.Import.optionrank t kifkis int, returns the number of keys strictly less thankint, otherwiseNone.
val to_sequence : ?order:[ `Increasing_key | `Decreasing_key ] -> ?keys_greater_or_equal_to:'k -> ?keys_less_or_equal_to:'k -> ('k, 'v, 'cmp) t -> ('k * 'v) Sequence.tto_sequence ?order ?keys_greater_or_equal_to ?keys_less_or_equal_to tgives a sequence of key-value pairs betweenkeys_less_or_equal_toandkeys_greater_or_equal_toinclusive, presented inorder. Ifkeys_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_keyis the default
val binary_search : ('k, 'v, 'cmp) t -> compare:(key:'k -> data:'v -> 'key -> Core_kernel__.Import.int) -> [ `Last_strictly_less_than | `Last_less_than_or_equal_to | `Last_equal_to | `First_equal_to | `First_greater_than_or_equal_to | `First_strictly_greater_than ] -> 'key -> ('k * 'v) Core_kernel__.Import.optionbinary_search t ~compare which eltreturns the(key, value)pair intspecified bycompareandwhich, if one exists.tmust be sorted in increasing order according tocompare, wherecompareandeltdividetinto three (possibly empty) segments:| < elt | = elt | > elt |
binary_searchreturns an element on the boundary of segments as specified bywhich. See the diagram below next to thewhichvariants.binary_searchdoes not check thatcompareorderst, and behavior is unspecified ifcomparedoesn't ordert. Behavior is also unspecified ifcomparemutatest.
val binary_search_segmented : ('k, 'v, 'cmp) t -> segment_of:(key:'k -> data:'v -> [ `Left | `Right ]) -> [ `Last_on_left | `First_on_right ] -> ('k * 'v) Core_kernel__.Import.optionbinary_search_segmented t ~segment_of whichtakes asegment_offunction that dividestinto two (possibly empty) segments:| segment_of elt = `Left | segment_of elt = `Right |
binary_search_segmentedreturns the(key, value)pair on the boundary of the segments as specified bywhich:`Last_on_leftyields the last element of the left segment, while`First_on_rightyields the first element of the right segment. It returnsNoneif the segment is empty.binary_search_segmenteddoes not check thatsegment_ofsegmentstas in the diagram, and behavior is unspecified ifsegment_ofdoesn't segmentt. Behavior is also unspecified ifsegment_ofmutatest.
val of_key_set : ('key, 'cmp) Base.Set.t -> f:('key -> 'data) -> ('key, 'data, 'cmp) tConvert a set to a map. Runs in
O(length t)time plus a call toffor each key to compute the associated data.
val key_set : ('key, _, 'cmp) t -> ('key, 'cmp) Base.Set.tConverts a map to a set of its keys. Runs in
O(length t)time.
val quickcheck_generator : ('k, 'cmp) comparator -> 'k Quickcheck.Generator.t -> 'v Quickcheck.Generator.t -> ('k, 'v, 'cmp) t Quickcheck.Generator.tval quickcheck_observer : 'k Quickcheck.Observer.t -> 'v Quickcheck.Observer.t -> ('k, 'v, 'cmp) t Quickcheck.Observer.tval quickcheck_shrinker : 'k Quickcheck.Shrinker.t -> 'v Quickcheck.Shrinker.t -> ('k, 'v, 'cmp) t Quickcheck.Shrinker.tThis 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:
- Map: polymorphic map operations
- Map.Poly: maps that use polymorphic comparison to order keys
- Key.Map: maps with a fixed key type that use
Key.compareto order keys
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.tThe 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 -> intBecause 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.
module Using_comparator : sig ... endmodule type Key_plain = Map_intf.Key_plainmodule type Key = Map_intf.Keymodule type Key_binable = Map_intf.Key_binablemodule type S_plain = Map_intf.S_plainmodule type S = Map_intf.Smodule type S_binable = Map_intf.S_binablemodule Make_plain_using_comparator : functor (Key : sig ... end) -> S_plain with type Key.t = Key.t with type Key.comparator_witness = Key.comparator_witnessmodule Make_using_comparator : functor (Key : sig ... end) -> S with type Key.t = Key.t with type Key.comparator_witness = Key.comparator_witnessmodule Make_binable : functor (Key : Key_binable) -> S_binable with type Key.t = Key.tmodule Make_binable_using_comparator : functor (Key : sig ... end) -> S_binable with type Key.t = Key.t with type Key.comparator_witness = Key.comparator_witnessmodule Key_bin_io = Map_intf.Key_bin_ioinclude Map_intf.For_deriving with type ('a, 'b, 'c) t := ('a, 'b, 'c) t
include Base.Map.For_deriving
module type Sexp_of_m = sig ... endmodule type M_of_sexp = sig ... endmodule type Compare_m = sig ... endmodule type Equal_m = sig ... endmodule type Hash_fold_m = Base.Hasher.Sval sexp_of_m__t : (module Sexp_of_m with type t = 'k) -> ('v -> Base.Sexp.t) -> ('k, 'v, 'cmp) t -> Base.Sexp.tval m__t_of_sexp : (module M_of_sexp with type comparator_witness = 'cmp and type t = 'k) -> (Base.Sexp.t -> 'v) -> Base.Sexp.t -> ('k, 'v, 'cmp) tval m__t_sexp_grammar : Base.Sexp.Private.Raw_grammar.tval compare_m__t : (module Compare_m) -> ('v -> 'v -> int) -> ('k, 'v, 'cmp) t -> ('k, 'v, 'cmp) t -> intval equal_m__t : (module Equal_m) -> ('v -> 'v -> bool) -> ('k, 'v, 'cmp) t -> ('k, 'v, 'cmp) t -> boolval hash_fold_m__t : (module Hash_fold_m with type t = 'k) -> (Base.Hash.state -> 'v -> Base.Hash.state) -> Base.Hash.state -> ('k, 'v, 'a) t -> Base.Hash.state
module M = Base.Map.Mval bin_shape_m__t : ('a, 'c) Map_intf.Key_bin_io.t -> Bin_prot.Shape.t -> Bin_prot.Shape.tval bin_size_m__t : ('a, 'c) Map_intf.Key_bin_io.t -> 'b Bin_prot.Size.sizer -> ('a, 'b, 'c) t Bin_prot.Size.sizerval bin_write_m__t : ('a, 'c) Map_intf.Key_bin_io.t -> 'b Bin_prot.Write.writer -> ('a, 'b, 'c) t Bin_prot.Write.writerval bin_read_m__t : ('a, 'c) Map_intf.Key_bin_io.t -> 'b Bin_prot.Read.reader -> ('a, 'b, 'c) t Bin_prot.Read.readerval __bin_read_m__t__ : ('a, 'c) Map_intf.Key_bin_io.t -> 'b Bin_prot.Read.reader -> (Core_kernel__.Import.int -> ('a, 'b, 'c) t) Bin_prot.Read.reader
module type Quickcheck_generator_m = sig ... endmodule type Quickcheck_observer_m = sig ... endmodule type Quickcheck_shrinker_m = sig ... endval quickcheck_generator_m__t : (module Quickcheck_generator_m with type comparator_witness = 'cmp and type t = 'k) -> 'v Quickcheck.Generator.t -> ('k, 'v, 'cmp) t Quickcheck.Generator.tval quickcheck_observer_m__t : (module Quickcheck_observer_m with type comparator_witness = 'cmp and type t = 'k) -> 'v Quickcheck.Observer.t -> ('k, 'v, 'cmp) t Quickcheck.Observer.tval quickcheck_shrinker_m__t : (module Quickcheck_shrinker_m with type comparator_witness = 'cmp and type t = 'k) -> 'v Quickcheck.Shrinker.t -> ('k, 'v, 'cmp) t Quickcheck.Shrinker.t
module Stable : sig ... endThe following functors may be used to define stable modules