Module Lists.Assoc

Functions for working with association lists (alists).

Constants

val empty : 'a list

empty is the empty alist.

Creation

val random : ?size:(unit -> int) -> key:(unit -> 'a) -> value:(unit -> 'b) -> unit -> ('a * 'b) list

(random ?size ~key ~value ()) is a random alist of size (size ()) (default: < 100), and each binding is given by (key (), value ()).

Accessors

val assoc : 'a -> ('a * 'b) list -> 'b

assoc is assoc.

val find : 'a -> ('a * 'b) list -> 'b

find is assoc.

val bindings : 'a -> ('a * 'b) list -> ('a * 'b) list

(bindings k alist) is the list of all bindings of key k in alist; tail recursive.

The bindings are returned in the order in which they occur.

Example:

  • (bindings 2 [1,1;2,2;3,3;2,4]) = [2,2; 2,4]

Invariants:

  • (bindings k [] = [])
  • (assocs k alist |> map (cons k)) = (bindings k alist)
  • (len (assocs k) = len (bindings k))
val assocs : 'a -> ('a * 'b) list -> 'b list

(assocs k alist) is the list of all the values in alist associated with key k; tail-recursive.

The values are in the order in which they occur in alist.

Example:

  • (assocs 2 [1,1;2,2;3,3;2,4]) = [2; 4]

See also coalesce for an efficient way to do assocs for each key in an alist.

val keys : ('a * 'b) list -> 'a list

(keys alist) is the list of all the keys in alist, order preserved; tail-recursive.

val values : ('a * 'b) list -> 'b list

(values alist) is the list of all the values in alist, order preserved; tail-recursive.

val project : 'a list -> ('a * 'b) list -> ('a * 'b) list

(project keys alist) is the subset of alist that contains only pairs with keys in keys.

Predicates

val mem : 'a -> ('a * 'b) list -> bool

mem is mem_assoc.

val has : ?kf:('a -> bool) -> ('b -> bool) -> ('a * 'b) list -> bool

(has ?kf vf xs) is true if (kf k && vf v) for any (k,v) pair in alist xs and false otherwise.

The default value for kf is (k true).

Modifiers

val add : 'a -> 'b -> ('a * 'b) list -> ('a * 'b) list

(add k v alist) is ((k,v) :: alist).

val remove_assoc : 'a -> ('a * 'b) list -> ('a * 'b) list

remove_assoc is List.remove_assoc.

val remove : 'a -> ('a * 'b) list -> ('a * 'b) list

(remove k alist) is like remove_assoc except: 1. it removes ALL matching pairs (not just the first) and 2. remove is tail-recursive.

val remove_keys : ('a * 'b) list -> ('a * 'c) list -> ('a * 'c) list

remove_keys igns alist is alist minus all associations whose keys are in igns.

val replace : ?all:bool -> ('a * 'b) -> ('a * 'b) list -> ('a * 'b) list

(replace ?all (k,v) alist) replaces some or all of the bindings for k in alist with (k,v); tail recursive.

If (all = false) (the default) then only the first binding is replaced.

The order of the bindings in alist is always preserved.

Invariants:

  • (replace (k,v) [] = [])
  • (replace (k,v) >> replace (k,v) = replace (k,v))
  • (replace (k,v) alist |> keys = keys alist)
val coalesce : ('a * 'b) list -> ('a * 'b list) list

(coalesce alist) converts an alist with repeating keys into one with unique keys bound to lists of values.

The order of elements in the result is sorted as by Stdlib.compare.

Invariants:

  • (coalesce xs |> flatmap (fun (k,vs) -> map (Pair.up k) vs) |> sort compare) = (sort compare xs)
  • (keys xs |> List.sort_uniq compare |> map (id *** flip assocs xs) |> sort compare) = (coalesce xs |> sort compare)
  • author Matt Teichman
val adjoin : ('a -> 'b -> 'b) -> 'b -> 'c -> 'a -> ('c * 'b) list -> ('c * 'b) list

(adjoin vadd empty) returns a function (f alist k v) that adjoins v to a collection of values associated with key k in association list alist; O(n).

See Map.Make.adjoin (which is more efficient) for a discussion and example.

val classify : ('a -> 'b) -> ('a -> 'c -> 'c) -> 'c -> 'a -> ('b * 'c) list -> ('b * 'c) list

(classify f add z x alist) returns a classifying adjoiner.

add could be cons and z, [], or add could be S.add and z, S.empty for some Set S.

f is a function that classifies an 'a by mapping it to some equivalence class; f could be even, or String.lowercase_ascii.

For example, foldr (classify even cons []) [] applied to an int list returns an alist of length 2 (the size of the codomain of even) mapping true to a list of even integers and false to a list of odd integers.

val incr : ?z:int -> ?i:int -> 'a -> ('a * int) list -> ('a * int) list

(incr ?z ?i k alist) is (adjoin (+) z k i alist), i.e. incr generates a function for counting instances of items (k) in an alist.

~z is the "zero" for the counters (default: 0); ~i is the increment (default: 1).

Combining Alists

val merge : ('a * 'b) list -> ('a * 'b) list -> ('a * 'b) list

(merge xs ys) merges the two alists; bindings in xs trump bindings in ys.

The order of the results is undefined.

val mergelong : ('a * 'b) list -> ('a * 'b) list -> ('a * 'b) list

(mergelong xs ys) is exactly the same as merge, but is significantly faster (up to 27 times) for long alists (100+).

val to_string : ?left:string -> ?sep:string -> ?right:string -> ('a -> string) -> ('b -> string) -> ('a * 'b) list -> string

(to_string ?left ?sep ?right f g xs) returns a string representation of xs.

to_string is (List.to_string ?left ?sep ?right (Pair.to_string f g)).

val print : ?left:string -> ?sep:string -> ?right:string -> ('a -> string) -> ('b -> string) -> ('a * 'b) list -> unit

(print ?left ?sep ?right f g xs) is (to_string ?left ?sep ?right f g xs >> print_endline).