Bare_structs.ListSourceinclude Bare_sigs.List.Sin-monad, preallocated nil
nil is []
nil_e is Ok []
nil_s is Lwt.return_nil
nil_es is Lwt.return (Ok [])
Shadowing unsafe functions to avoid all exceptions.
Return option rather than raise Not_found, Failure _, or Invalid_argument _
hd xs is the head (first element) of the list or None if the list is empty.
tl xs is the tail of the list (the whole list except the first element) or None if the list is empty.
nth xs n is the nth element of the list or None if the list has fewer than n elements.
nth xs 0 = hd xs
nth_opt is an alias for nth provided for backwards compatibility.
last x xs is the last element of the list xs or x if xs is empty.
The primary intended use for last is after destructing a list: match l with | None -> … | Some x :: xs -> last x xs but it can also be used for a default value: last default_value_if_empty xs.
last_opt xs is the last element of the list xs or None if the list xs is empty.
find predicate xs is the first element x of the list xs such that predicate x is true or None if the list xs has no such element.
find_opt is an alias for find provided for backwards compatibility.
mem ~equal a l is true iff there is an element e of l such that equal a e.
assoc ~equal k kvs is Some v such that (k', v) is the first pair in the list such that equal k' k or None if the list contains no such pair.
assoc_opt is an alias for assoc provided for backwards compatibility.
assq k kvs is the same as assoc ~equal:Stdlib.( == ) k kvs: it uses the physical equality.
assq_opt is an alias for assq provided for backwards compatibility.
mem_assoc ~equal k l is equivalent to Option.is_some @@ assoc ~equal k l.
remove_assoc ~equal k l is l without the first element (k', _) such that equal k k'.
remove_assoq k l is remove_assoc ~equal:Stdlib.( == ) k l.
val init :
when_negative_length:'trace ->
int ->
(int -> 'a) ->
('a list, 'trace) Stdlib.resultinit ~when_negative_length n f is Error when_negative_length if n is strictly negative and Ok (Stdlib.List.init n f) otherwise.
These safe-wrappers take an explicit value to handle the case of lists of unequal length.
val combine :
when_different_lengths:'trace ->
'a list ->
'b list ->
(('a * 'b) list, 'trace) Stdlib.resultcombine ~when_different_lengths l1 l2 is either
Error when_different_lengths if List.length l1 <> List.length l2l1 and l2E.g., combine ~when_different_lengths [] [] = Ok []
E.g., combine ~when_different_lengths [1; 2] ['a'; 'b'] = Ok [(1,'a'); (2, 'b')]
E.g., combine ~when_different_lengths:() [1] [] = Error ()
Note: combine ~when_different_lengths l1 l2 is equivalent to try Ok (Stdlib.List.combine l1 l2) with Invalid_argument _ -> when_different_lengths
The same equivalence almost holds for the other double traversors below. The notable difference is if the functions passed as argument to the traversors raise the Invalid_argument _ exception.
val rev_combine :
when_different_lengths:'trace ->
'a list ->
'b list ->
(('a * 'b) list, 'trace) Stdlib.resultrev_combine ~when_different_lengths xs ys is rev (combine ~when_different_lengths xs ys) but more efficient.
val iter2 :
when_different_lengths:'trace ->
('a -> 'b -> unit) ->
'a list ->
'b list ->
(unit, 'trace) Stdlib.resultval map2 :
when_different_lengths:'trace ->
('a -> 'b -> 'c) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.resultval rev_map2 :
when_different_lengths:'trace ->
('a -> 'b -> 'c) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.resultval fold_left2 :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> 'a) ->
'a ->
'b list ->
'c list ->
('a, 'trace) Stdlib.resultval fold_right2 :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> 'c) ->
'a list ->
'b list ->
'c ->
('c, 'trace) Stdlib.resultThis function is not tail-recursive
fold_left_map f a xs is a combination of fold_left and map that maps over all elements of xs and threads an accumulator with initial value a through calls to f.
val for_all2 :
when_different_lengths:'trace ->
('a -> 'b -> bool) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.resultval exists2 :
when_different_lengths:'trace ->
('a -> 'b -> bool) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.resultThe functions below are strict extensions of the standard Stdlib.List module. It is for result-, lwt- and lwt-result-aware variants. The meaning of the suffix is as described above, in Lwtreslib, and in Sigs.Seq.
Note that for asynchronous variants (_s, _es, _p, and _ep), if the length parameter is negative, then the promise is returned already fulfilled with Error when_different_lengths.
val init_e :
when_negative_length:'trace ->
int ->
(int -> ('a, 'trace) Stdlib.result) ->
('a list, 'trace) Stdlib.resultval init_s :
when_negative_length:'trace ->
int ->
(int -> 'a Lwt.t) ->
('a list, 'trace) Stdlib.result Lwt.tval init_es :
when_negative_length:'trace ->
int ->
(int -> ('a, 'trace) Stdlib.result Lwt.t) ->
('a list, 'trace) Stdlib.result Lwt.tval init_ep :
when_negative_length:'error ->
int ->
(int -> ('a, 'error) Stdlib.result Lwt.t) ->
('a list, 'error list) Stdlib.result Lwt.tval init_p :
when_negative_length:'trace ->
int ->
(int -> 'a Lwt.t) ->
('a list, 'trace) Stdlib.result Lwt.tval find_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a option, 'trace) Stdlib.resultval find_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a option, 'trace) Stdlib.result Lwt.trev_filter f l is rev (filter f l) but more efficient.
val rev_filter_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a list, 'trace) Stdlib.resultval filter_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a list, 'trace) Stdlib.resultval rev_filter_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list, 'trace) Stdlib.result Lwt.tval filter_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list, 'trace) Stdlib.result Lwt.tval filter_ep :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list, 'trace list) Stdlib.result Lwt.tval rev_partition_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a list * 'a list, 'trace) Stdlib.resultval partition_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a list * 'a list, 'trace) Stdlib.resultval rev_partition_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list * 'a list, 'trace) Stdlib.result Lwt.tval partition_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list * 'a list, 'trace) Stdlib.result Lwt.tval partition_ep :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list * 'a list, 'trace list) Stdlib.result Lwt.tval iter_es :
('a -> (unit, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(unit, 'trace) Stdlib.result Lwt.tval iter_ep :
('a -> (unit, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(unit, 'trace list) Stdlib.result Lwt.tval iteri_e :
(int -> 'a -> (unit, 'trace) Stdlib.result) ->
'a list ->
(unit, 'trace) Stdlib.resultval iteri_es :
(int -> 'a -> (unit, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(unit, 'trace) Stdlib.result Lwt.tval iteri_ep :
(int -> 'a -> (unit, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(unit, 'trace list) Stdlib.result Lwt.tval map_es :
('a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.tval map_ep :
('a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace list) Stdlib.result Lwt.tval mapi_e :
(int -> 'a -> ('b, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.resultval mapi_es :
(int -> 'a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.tval mapi_ep :
(int -> 'a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace list) Stdlib.result Lwt.tval rev_map_e :
('a -> ('b, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.resultval rev_map_es :
('a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.tval rev_map_ep :
('a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace list) Stdlib.result Lwt.tval rev_mapi_e :
(int -> 'a -> ('b, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.resultval rev_mapi_es :
(int -> 'a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.tval rev_mapi_ep :
(int -> 'a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace list) Stdlib.result Lwt.tval rev_filter_map_e :
('a -> ('b option, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.resultval filter_map_e :
('a -> ('b option, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.resultval rev_filter_map_es :
('a -> ('b option, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.tval filter_map_es :
('a -> ('b option, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.tval filter_map_ep :
('a -> ('b option, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace list) Stdlib.result Lwt.tval concat_map_e :
('a -> ('b list, 'error) Stdlib.result) ->
'a list ->
('b list, 'error) Stdlib.resultval concat_map_es :
('a -> ('b list, 'error) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'error) Stdlib.result Lwt.tval concat_map_ep :
('a -> ('b list, 'error) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'error list) Stdlib.result Lwt.tval fold_left_e :
('a -> 'b -> ('a, 'trace) Stdlib.result) ->
'a ->
'b list ->
('a, 'trace) Stdlib.resultval fold_left_es :
('a -> 'b -> ('a, 'trace) Stdlib.result Lwt.t) ->
'a ->
'b list ->
('a, 'trace) Stdlib.result Lwt.tval fold_left_map_e :
('a -> 'b -> ('a * 'c, 'trace) Stdlib.result) ->
'a ->
'b list ->
('a * 'c list, 'trace) Stdlib.resultfold_left_map_e f a xs is a combination of fold_left_e and map_e that maps over all elements of xs and threads an accumulator with initial value a through calls to f. The list is traversed from left to right and the first encountered error is returned.
fold_left_map_s f a xs is a combination of fold_left_s and map_s that maps over all elements of xs and threads an accumulator with initial value a through calls to f.
val fold_left_map_es :
('a -> 'b -> ('a * 'c, 'trace) Stdlib.result Lwt.t) ->
'a ->
'b list ->
('a * 'c list, 'trace) Stdlib.result Lwt.tfold_left_map_es f a xs is a combination of fold_left_es and map_es that maps over all elements of xs and threads an accumulator with initial value a through calls to f. The list is traversed from left to right and the first encountered error is returned.
val fold_left_i_e :
(int -> 'a -> 'b -> ('a, 'trace) Stdlib.result) ->
'a ->
'b list ->
('a, 'trace) Stdlib.resultval fold_left_i_es :
(int -> 'a -> 'b -> ('a, 'trace) Stdlib.result Lwt.t) ->
'a ->
'b list ->
('a, 'trace) Stdlib.result Lwt.tval fold_right_e :
('a -> 'b -> ('b, 'trace) Stdlib.result) ->
'a list ->
'b ->
('b, 'trace) Stdlib.resultThis function is not tail-recursive
This function is not tail-recursive
val fold_right_es :
('a -> 'b -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b ->
('b, 'trace) Stdlib.result Lwt.tThis function is not tail-recursive
As mentioned above, there are no _p and _ep double-traversors. Use combine (and variants) to circumvent this.
val iter2_e :
when_different_lengths:'trace ->
('a -> 'b -> (unit, 'trace) Stdlib.result) ->
'a list ->
'b list ->
(unit, 'trace) Stdlib.resultval iter2_s :
when_different_lengths:'trace ->
('a -> 'b -> unit Lwt.t) ->
'a list ->
'b list ->
(unit, 'trace) Stdlib.result Lwt.tval iter2_es :
when_different_lengths:'trace ->
('a -> 'b -> (unit, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b list ->
(unit, 'trace) Stdlib.result Lwt.tval map2_e :
when_different_lengths:'trace ->
('a -> 'b -> ('c, 'trace) Stdlib.result) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.resultval map2_s :
when_different_lengths:'trace ->
('a -> 'b -> 'c Lwt.t) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result Lwt.tval map2_es :
when_different_lengths:'trace ->
('a -> 'b -> ('c, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result Lwt.tval rev_map2_e :
when_different_lengths:'trace ->
('a -> 'b -> ('c, 'trace) Stdlib.result) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.resultval rev_map2_s :
when_different_lengths:'trace ->
('a -> 'b -> 'c Lwt.t) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result Lwt.tval rev_map2_es :
when_different_lengths:'trace ->
('a -> 'b -> ('c, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result Lwt.tval fold_left2_e :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> ('a, 'trace) Stdlib.result) ->
'a ->
'b list ->
'c list ->
('a, 'trace) Stdlib.resultval fold_left2_s :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> 'a Lwt.t) ->
'a ->
'b list ->
'c list ->
('a, 'trace) Stdlib.result Lwt.tval fold_left2_es :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> ('a, 'trace) Stdlib.result Lwt.t) ->
'a ->
'b list ->
'c list ->
('a, 'trace) Stdlib.result Lwt.tval fold_right2_e :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> ('c, 'trace) Stdlib.result) ->
'a list ->
'b list ->
'c ->
('c, 'trace) Stdlib.resultThis function is not tail-recursive
val fold_right2_s :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> 'c Lwt.t) ->
'a list ->
'b list ->
'c ->
('c, 'trace) Stdlib.result Lwt.tThis function is not tail-recursive
val fold_right2_es :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> ('c, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b list ->
'c ->
('c, 'trace) Stdlib.result Lwt.tThis function is not tail-recursive
val for_all_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
(bool, 'trace) Stdlib.resultval for_all_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(bool, 'trace) Stdlib.result Lwt.tval for_all_ep :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(bool, 'trace list) Stdlib.result Lwt.tval exists_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
(bool, 'trace) Stdlib.resultval exists_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(bool, 'trace) Stdlib.result Lwt.tval exists_ep :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(bool, 'trace list) Stdlib.result Lwt.tAs mentioned above, there are no _p and _ep double-scanners. Use combine (and variants) to circumvent this.
val for_all2_e :
when_different_lengths:'trace ->
('a -> 'b -> (bool, 'trace) Stdlib.result) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.resultval for_all2_s :
when_different_lengths:'trace ->
('a -> 'b -> bool Lwt.t) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result Lwt.tval for_all2_es :
when_different_lengths:'trace ->
('a -> 'b -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result Lwt.tval exists2_e :
when_different_lengths:'trace ->
('a -> 'b -> (bool, 'trace) Stdlib.result) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.resultval exists2_s :
when_different_lengths:'trace ->
('a -> 'b -> bool Lwt.t) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result Lwt.tval exists2_es :
when_different_lengths:'trace ->
('a -> 'b -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result Lwt.tThese are primarily intended to be used for preprocessing before applying a traversor to the resulting list of pairs. They give alternatives to the when_different_lengths mechanism of the immediate double-traversors above.
In case the semantic of, say, map2_es was unsatisfying, one can use map_es on a combine-preprocessed pair of lists. The different variants of combine give different approaches to different-length handling.
combine_drop ll lr is a list l of pairs of elements taken from the common-length prefix of ll and lr. The suffix of whichever list is longer (if any) is dropped.
More formally nth l n is:
None if n >= min (length ll) (length lr)Some (Option.get @@ nth ll n, Option.get @@ nth lr n) otherwiseA type like result but which is symmetric
val combine_with_leftovers :
'a list ->
'b list ->
('a * 'b) list * ('a, 'b) left_or_right_list optioncombine_with_leftovers ll lr is a tuple (combined, leftover) where combined is combine_drop ll lr and leftover is either `Left lsuffix or `Right rsuffix depending on which of ll or lr is longer. leftover is None if the two lists have the same length.