include Bare_sigs.List.S
type 'a t = 'a list =
| []
| :: of 'a * 'a list
Constructors and some such
val nil_e : ('a list, 'trace) Stdlib.result
val nil_s : 'a list Lwt.t
val nil_es : ('a list, 'trace) Stdlib.result Lwt.t
nil_es
is Lwt.return (Ok [])
val cons : 'a -> 'a list -> 'a list
val is_empty : 'a list -> bool
is_empty xs
is true
iff xs
is []
Safe wrappers
This part of the module simply shadows some functions from Stdlib.List
with exceptionless variants. As per the design principles of Lwtreslib,
- functions which may fail with
Not_found
or otherwise from unavailability of data return an option
instead, - function which may fail with
Invalid_argument _
or otherwise from malformedness of input receive an additional parameter to return as an Error
instead, - functions which perform polymorphic comparison receive an additional parameter for monomorphic comparison instead.
val hd : 'a list -> 'a option
hd xs
is the head (first element) of the list or None
if the list is empty.
val tl : 'a list -> 'a list option
tl xs
is the tail of the list (the whole list except the first element) or None
if the list is empty.
val nth : 'a list -> int -> 'a option
nth xs n
is the n
th element of the list or None
if the list has fewer than n
elements.
For example, nth xs 0 = hd xs
and nth ['x'; 'y'] 1 = Some 'y'
.
val nth_opt : 'a list -> int -> 'a option
nth_opt
is an alias for nth
provided for compatibility with Stdlib.List
.
val last : 'a -> 'a list -> 'a
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 | [] -> … | x :: xs -> last x xs
but it can also be used for a default value: last default_value_if_empty xs
.
val last_opt : 'a list -> 'a option
last_opt xs
is the last element of the list xs
or None
if the list xs
is empty.
val find : ('a -> bool) -> 'a list -> 'a option
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.
val find_opt : ('a -> bool) -> 'a list -> 'a option
find_opt
is an alias for find
provided for compatibility with Stdlib.List
.
val find_map : ('a -> 'b option) -> 'a list -> 'b option
find_map f xs
applies f
to each of the elements of xs
until it returns Some _
at which point it is returned. If no such elements are found then it returns None
.
Note that it only applies f
to a prefix of xs
. It doesn't apply f
to the elements of xs
which are after the found element. Consequently, find_map f xs
has better performance and a different semantic than calling map
and find
separately.
val mem : equal:('a -> 'a -> bool) -> 'a -> 'a list -> bool
mem ~equal a l
is true
iff there is an element e
of l
such that equal a e
.
val memq : 'a -> 'a list -> bool
memq a l
is the same as mem ~equal:Stdlib.( == ) a l
: it uses the physical equality.
val assoc : equal:('a -> 'a -> bool) -> 'a -> ('a * 'b) list -> 'b option
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.
val assoc_opt : equal:('a -> 'a -> bool) -> 'a -> ('a * 'b) list -> 'b option
assoc_opt
is an alias for assoc
provided for compatibility with Stdlib.List
.
val assq : 'a -> ('a * 'b) list -> 'b option
assq k kvs
is the same as assoc ~equal:Stdlib.( == ) k kvs
: it uses the physical equality.
val assq_opt : 'a -> ('a * 'b) list -> 'b option
assq_opt
is an alias for assq
provided for compatibility with Stdlib.List
.
val mem_assoc : equal:('a -> 'a -> bool) -> 'a -> ('a * 'b) list -> bool
mem_assoc ~equal k l
is equivalent to Option.is_some @@ assoc ~equal k l
.
val mem_assq : 'a -> ('a * 'b) list -> bool
mem_assq k l
is mem_assoc ~equal:Stdlib.( == ) k l
.
val remove_assoc :
equal:('a -> 'a -> bool) ->
'a ->
('a * 'b) list ->
('a * 'b) list
remove_assoc ~equal k l
is l
without the first element (k', _)
such that equal k k'
.
val remove_assq : 'a -> ('a * 'b) list -> ('a * 'b) list
remove_assoq k l
is remove_assoc ~equal:Stdlib.( == ) k l
.
Initialisation
val init :
when_negative_length:'trace ->
int ->
(int -> 'a) ->
('a list, 'trace) Stdlib.result
init ~when_negative_length n f
is a list of n
elements f 0
, f 1
, etc.
If n
is negative, it is Error when_negative_length
instead.
Basic traversal
val length : 'a list -> int
length xs
is the number of elements in xs
.
length []
is 0
, length ['x']
is 1
, etc.
val rev : 'a list -> 'a list
rev xs
is a list with the elements appearing in the reverse order as in xs
.
rev ['x'; 'y']
is 'y'; 'x'
val concat : 'a list list -> 'a list
concat xs
is a list containing the elements of the elements of xs
.
concat [['x'; 'y']; ['a'; 'b']]
is ['x'; 'y'; 'a'; 'b']
val append : 'a list -> 'a list -> 'a list
append xs ys
is a list containing the elements of xs
and the elements of ys
, in this order.
concat ['x'; 'y'] ['a'; 'b']
is ['x'; 'y'; 'a'; 'b']
val rev_append : 'a list -> 'a list -> 'a list
rev_append xs ys
is append (rev xs) ys
but more efficient. In other words, rev_append xs ys
is a list containing the elements of xs in reverse order followed by the elements of ys
.
There are two main use-cases for rev_append
. First, you should use rev_append
when the order of elements is unimportant. In this case you simply replace append xs ys
with rev_append xs ys
.
Second, you can use rev_append
on an already reversed list. You may obtain an already reversed list from any of the other rev_*
functions of this module, or simply via your own traversal. In this case, you replace, say, append (map f xs) ys
with rev_append (rev_map f xs) ys
.
val flatten : 'a list list -> 'a list
flatten
is an alias for concat
.
Double-list traversals
These safe-wrappers take an explicit value to handle the case of lists of unequal length. This value is passed as a named parameter: when_different_lengths
.
Note that the traversal function passed as argument (if any) is applied to the common prefix of the two lists, even if they are of different lengths. E.g., in map2 f ['x', 'y'] ['a']
the call f 'x' 'a'
is made and all its side-effects are performed before the value Error when_different_lengths
is returned
val combine :
when_different_lengths:'trace ->
'a list ->
'b list ->
(('a * 'b) list, 'trace) Stdlib.result
combine ~when_different_lengths l1 l2
is either
Error when_different_lengths
if List.length l1 <> List.length l2
- a list of pairs of elements from
l1
and l2
E.g., combine ~when_different_lengths [] []
is Ok []
E.g., combine ~when_different_lengths [1; 2] ['a'; 'b']
is Ok [(1,'a'); (2, 'b')]
E.g., combine ~when_different_lengths:"wrong" [1] []
is Error "wrong"
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.result
rev_combine ~when_different_lengths xs ys
is rev (combine ~when_different_lengths xs ys)
but more efficient.
val split : ('a * 'b) list -> 'a list * 'b list
split xs
is (List.map fst xs, List.map snd xs)
but more efficient.
val iter2 :
when_different_lengths:'trace ->
('a -> 'b -> unit) ->
'a list ->
'b list ->
(unit, 'trace) Stdlib.result
iter2 ~when_different_lengths f xs ys
is f x0 y0; f x1 y1; …
.
Remember that, even if the lists are of different lengths, the function f
is applied to the common prefix of xs
and ys
. This is true for other traversals, but especially relevant to iter
which is commonly used for side-effects.
val map2 :
when_different_lengths:'trace ->
('a -> 'b -> 'c) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result
map2 ~when_different_lengths f xs ys
is a list with elements f x0 y0
, f x1 y1
, etc.
Remember that, even if the lists are of different lengths, the function f
is applied to the common prefix of xs
and ys
. Beware of side-effects and computational cost.
val rev_map2 :
when_different_lengths:'trace ->
('a -> 'b -> 'c) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result
rev_map2 ~when_different_lengths f xs ys
is Result.map rev @@ map2 ~when_different_lengths f xs ys
but more efficient.
Remember that, even if the lists are of different lengths, the function f
is applied to the common prefix of xs
and ys
. Beware of side-effects and computational cost.
val fold_left2 :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> 'a) ->
'a ->
'b list ->
'c list ->
('a, 'trace) Stdlib.result
fold_left2 ~when_different_lengths f init xs ys
is … (f (f init x0 y0) x1 y1)
.
Remember that, even if the lists are of different lengths, the function f
is applied to the common prefix of xs
and ys
. Beware of side-effects and computational cost.
val fold_right2 :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> 'c) ->
'a list ->
'b list ->
'c ->
('c, 'trace) Stdlib.result
fold_right2 ~when_different_lengths f xs ys init
is f x0 y0 (f x1 y1 (…))
.
This function is not tail-recursive.
Note that unlike the left-to-right double-list traversors, fold_right2
only calls f
if the lists are of the same length.
val for_all2 :
when_different_lengths:'trace ->
('a -> 'b -> bool) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result
for_all2 ~when_different_lengths f xs ys
is f x0 y0 && f x1 y1 && …
.
The function stops early if it encounters elements xn
, yn
such that f
xn yn
is false
. (This is consistent with the short-circuit, lazy evaluation strategy of &&
in the description above.)
Also note that, if such an element is found in the common prefix of xs
and ys
, then the function returns Ok false
even if xs
and ys
are of different lengths.
Examples:
for_all2 ~when_different_lengths (=) [] []
is Ok true
for_all2 ~when_different_lengths (=) ['x'] ['a']
is Ok false
for_all2 ~when_different_lengths (=) ['x'; 'y'] ['a']
is Ok false
for_all2 ~when_different_lengths (=) ['x'] ['x']
is Ok true
for_all2 ~when_different_lengths (=) ['x'; 'y'] ['x']
is Error when_different_lengths
for_all2 ~when_different_lengths (=) ['x'; 'y'] ['x'; 'b']
is Ok false
for_all2 ~when_different_lengths (=) ['x'; 'y'] ['x'; 'y'; 'c']
is Error when_different_lengths
Remember that, when it returns Error when_different_lengths
, the function f
has already been applied to the common prefix of xs
and ys
. Beware of side-effects and computational cost.
val exists2 :
when_different_lengths:'trace ->
('a -> 'b -> bool) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result
exists2 ~when_different_lengths f xs ys
is f x0 y0 || f x1 y1 || …
.
The function stops early if it encounters elements xn
, yn
such that f
xn yn
is true
. (This is consistent with the short-circuit, lazy evaluation strategy of ||
in the description above.)
Also note that, if such an element is found in the common prefix of xs
and ys
, then the function returns Ok true
even if xs
and ys
are of different lengths.
Examples:
exists2 ~when_different_lengths (=) [] []
is Ok false
exists2 ~when_different_lengths (=) ['x'] ['a']
is Ok false
exists2 ~when_different_lengths (=) ['x'; 'y'] ['a']
is Error when_different_lengths
exists2 ~when_different_lengths (=) ['x'] ['x']
is Ok true
exists2 ~when_different_lengths (=) ['x'; 'y'] ['x']
is Ok true
Remember that, when it returns Error when_different_lengths
, the function f
has already been applied to the common prefix of xs
and ys
. Beware of side-effects and computational cost.
Monad-aware variants
The 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
.
Initialisation variants
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.result
init_e
is a Result-aware variant of init
.
val init_s :
when_negative_length:'trace ->
int ->
(int -> 'a Lwt.t) ->
('a list, 'trace) Stdlib.result Lwt.t
init_s
is an Lwt-aware variant of init
.
val init_es :
when_negative_length:'trace ->
int ->
(int -> ('a, 'trace) Stdlib.result Lwt.t) ->
('a list, 'trace) Stdlib.result Lwt.t
init_es
is an Lwt-Result-aware variant of init
.
val init_ep :
when_negative_length:'error ->
int ->
(int -> ('a, 'error) Stdlib.result Lwt.t) ->
('a list, 'error list) Stdlib.result Lwt.t
init_ep
is a variant of init_es
where the promises are evaluated concurrently.
val init_p :
when_negative_length:'trace ->
int ->
(int -> 'a Lwt.t) ->
('a list, 'trace) Stdlib.result Lwt.t
init_p
is a variant of init_s
where the promises are evaluated concurrently.
Query variants
val find_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a option, 'trace) Stdlib.result
find_e
is a Result-aware variant of find
.
val find_s : ('a -> bool Lwt.t) -> 'a list -> 'a option Lwt.t
find_s
is an Lwt-aware variant of find
.
val find_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a option, 'trace) Stdlib.result Lwt.t
find_es
is an Lwt-Result-aware variant of find
.
val find_map_e :
('a -> ('b option, 'trace) Stdlib.result) ->
'a list ->
('b option, 'trace) Stdlib.result
find_map_e
is a Result-aware variant of find_map
.
val find_map_s : ('a -> 'b option Lwt.t) -> 'a list -> 'b option Lwt.t
find_map_s
is an Lwt-aware variant of find_map
.
val find_map_es :
('a -> ('b option, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b option, 'trace) Stdlib.result Lwt.t
find_map_es
is an Lwt-Result-aware variant of find_map
.
val filter : ('a -> bool) -> 'a list -> 'a list
filter f xs
is the list of all the elements xn
of xs
such that f xn
is true
.
filter (fun x -> x > 10) [0; 2; 19; 22; -1; 3; 11]
is [19; 22; 11]
val filteri : (int -> 'a -> bool) -> 'a list -> 'a list
filteri
is similar to filter
but the predicate also receives the element's index as an argument.
val find_all : ('a -> bool) -> 'a list -> 'a list
find_all
is an alias for filter
.
val rev_filter : ('a -> bool) -> 'a list -> 'a list
rev_filter f l
is rev (filter f l)
but more efficient.
val rev_filteri : (int -> 'a -> bool) -> 'a list -> 'a list
rev_filteri f l
is rev (filteri f l)
but more efficient.
val rev_filter_some : 'a option list -> 'a list
rev_filter_some xs
is rev @@ filter_some xs
but more efficient.
val filter_some : 'a option list -> 'a list
filter_some
extracts all the payloads of the Some
variants. The order is preserved.
filter_some [None; Some 'a'; None; None; Some 'z'; Some 'u']
is ['a'; 'z'; 'u']
.
val rev_filter_ok : ('a, 'b) Stdlib.result list -> 'a list
rev_filter_ok rs
is rev @@ filter_ok rs
but more efficient.
val filter_ok : ('a, 'b) Stdlib.result list -> 'a list
filter_ok
extracts all the payloads of the Ok
variants. The order is preserved.
filter_ok [Error 3; Ok 'a'; Error 3; Error 5; Ok 'z'; Ok 'u']
is ['a'; 'z'; 'u']
.
val rev_filter_error : ('a, 'b) Stdlib.result list -> 'b list
rev_filter_error rs
is rev @@ filter_error rs
but more efficient.
val filter_error : ('a, 'b) Stdlib.result list -> 'b list
filter_error
extracts all the payloads of the Error
variants. The order is preserved.
filter_ok [Error 3; Ok 'a'; Error 3; Error 5; Ok 'z'; Ok 'u']
is [3; 3; 5]
.
val rev_filter_left : ('a, 'b) Stdlib.Either.t list -> 'a list
rev_filter_left es
is rev @@ filter_left es
but more efficient.
val filter_left : ('a, 'b) Stdlib.Either.t list -> 'a list
filter_left
extracts all the payloads of the Left
variants. The order is preserved.
filter_left [Right 3; Left 'a'; Right 3; Right 5; Left 'z'; Left 'u']
is ['a'; 'z'; 'u']
.
val rev_filter_right : ('a, 'b) Stdlib.Either.t list -> 'b list
rev_filter_right es
is rev @@ filter_right es
but more efficient.
val filter_right : ('a, 'b) Stdlib.Either.t list -> 'b list
filter_right
extracts all the payloads of the Right
variants. The order is preserved.
filter_right [Right 3; Left 'a'; Right 3; Right 5; Left 'z'; Left 'u']
is [3; 3; 5]
.
val rev_filter_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a list, 'trace) Stdlib.result
rev_filter_e
is a Result-aware variant of rev_filter
.
val filter_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a list, 'trace) Stdlib.result
filter_e
is a Result-aware variant of filter
.
val rev_filter_s : ('a -> bool Lwt.t) -> 'a list -> 'a list Lwt.t
rev_filter_s
is an Lwt-aware variant of rev_filter
.
val filter_s : ('a -> bool Lwt.t) -> 'a list -> 'a list Lwt.t
filter_s
is an Lwt-aware variant of filter
.
val rev_filter_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list, 'trace) Stdlib.result Lwt.t
rev_filter_es
is an Lwt-Result-aware variant of rev_filter
.
val filter_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list, 'trace) Stdlib.result Lwt.t
filter_es
is an Lwt-Result-aware variant of filter
.
val filter_ep :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list, 'trace list) Stdlib.result Lwt.t
filter_ep
is a variant of filter_es
where the promises are evaluated concurrently.
val filter_p : ('a -> bool Lwt.t) -> 'a list -> 'a list Lwt.t
filter_p
is a variant of filter_s
where the promises are evaluated concurrently.
val rev_filteri_e :
(int -> 'a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a list, 'trace) Stdlib.result
rev_filteri_e
is a Result-aware variant of rev_filteri
.
val filteri_e :
(int -> 'a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a list, 'trace) Stdlib.result
filteri_e
is a Result-aware variant of filteri
.
val rev_filteri_s : (int -> 'a -> bool Lwt.t) -> 'a list -> 'a list Lwt.t
val filteri_s : (int -> 'a -> bool Lwt.t) -> 'a list -> 'a list Lwt.t
filteri_s
is an Lwt-aware variant of filteri
.
val rev_filteri_es :
(int -> 'a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list, 'trace) Stdlib.result Lwt.t
rev_filteri_es
is an Lwt-Result-aware variant of rev_filteri
.
val filteri_es :
(int -> 'a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list, 'trace) Stdlib.result Lwt.t
filteri_es
is an Lwt-Result-aware variant of filteri
.
val filteri_ep :
(int -> 'a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list, 'trace list) Stdlib.result Lwt.t
filteri_ep
is a variant of filteri_es
where the promises are evaluated concurrently.
val filteri_p : (int -> 'a -> bool Lwt.t) -> 'a list -> 'a list Lwt.t
filteri_p
is a variant of filteri_s
where the promises are evaluated concurrently.
val rev_partition : ('a -> bool) -> 'a list -> 'a list * 'a list
rev_partition f xs
is let rt, rf = partition f xs in (rev rt, rev rf)
but more efficient.
val partition : ('a -> bool) -> 'a list -> 'a list * 'a list
partition f xs
is a couple of lists (ts, fs)
where ts
contains all the elements of xs
such that f x
is true
and fs
contains all the elements of xs
such that f x
is false
.
The function f
is applied once to each element of xs
.
val rev_partition_map :
('a -> ('b, 'c) Stdlib.Either.t) ->
'a list ->
'b list * 'c list
rev_partition_map f xs
is let rt, rf = partition_map f xs in (rev rt, rev rf)
but more efficient.
val partition_map :
('a -> ('b, 'c) Stdlib.Either.t) ->
'a list ->
'b list * 'c list
partition_map f xs
applies f
to each of the element of xs
and returns a couple of lists (ls, rs)
where ls
contains all the l
such that f x
is Left l
and rs
contains all the r
such that f x
is Right r
.
val rev_partition_result : ('a, 'b) Stdlib.result list -> 'a list * 'b list
rev_partition_result rs
is partition_result @@ rev rs
but more efficient.
val partition_result : ('a, 'b) Stdlib.result list -> 'a list * 'b list
partition_result rs
is a tuple of lists (os, es)
where os
contains all the payloads of Ok
variants of rs
and es
contains all the payloads of Error
variants of rs
.
partition_result rs
is (filter_ok rs, filter_error rs)
but more efficient.
val rev_partition_either : ('a, 'b) Stdlib.Either.t list -> 'a list * 'b list
rev_partition_either rs
is partition_either @@ rev rs
but more efficient.
val partition_either : ('a, 'b) Stdlib.Either.t list -> 'a list * 'b list
partition_either es
is a tuple of lists (ls, rs)
where ls
contains all the payloads of Left
variants of ls
and rs
contains all the payloads of Right
variants of es
.
partition_either es
is (filter_left es, filter_right es)
but more efficient.
val rev_partition_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a list * 'a list, 'trace) Stdlib.result
val partition_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
('a list * 'a list, 'trace) Stdlib.result
partition_e
is a Result-aware variant of partition
.
val rev_partition_s :
('a -> bool Lwt.t) ->
'a list ->
('a list * 'a list) Lwt.t
val partition_s : ('a -> bool Lwt.t) -> 'a list -> ('a list * 'a list) Lwt.t
partition_s
is an Lwt-aware variant of partition
.
val rev_partition_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list * 'a list, 'trace) Stdlib.result Lwt.t
rev_partition_es
is an Lwt-Result-aware variant of rev_partition
.
val partition_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list * 'a list, 'trace) Stdlib.result Lwt.t
partition_es
is an Lwt-Result-aware variant of partition
.
val partition_ep :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('a list * 'a list, 'trace list) Stdlib.result Lwt.t
partition_ep
is a variant of partition_es
where the promises are evaluated concurrently.
val partition_p : ('a -> bool Lwt.t) -> 'a list -> ('a list * 'a list) Lwt.t
partition_p
is a variant of partition_s
where the promises are evaluated concurrently.
val rev_partition_map_e :
('a -> (('b, 'c) Stdlib.Either.t, 'trace) Stdlib.result) ->
'a list ->
('b list * 'c list, 'trace) Stdlib.result
val partition_map_e :
('a -> (('b, 'c) Stdlib.Either.t, 'trace) Stdlib.result) ->
'a list ->
('b list * 'c list, 'trace) Stdlib.result
val rev_partition_map_s :
('a -> ('b, 'c) Stdlib.Either.t Lwt.t) ->
'a list ->
('b list * 'c list) Lwt.t
val partition_map_s :
('a -> ('b, 'c) Stdlib.Either.t Lwt.t) ->
'a list ->
('b list * 'c list) Lwt.t
val rev_partition_map_es :
('a -> (('b, 'c) Stdlib.Either.t, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list * 'c list, 'trace) Stdlib.result Lwt.t
val partition_map_es :
('a -> (('b, 'c) Stdlib.Either.t, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list * 'c list, 'trace) Stdlib.result Lwt.t
partition_map_es
is an Lwt-Result-aware variant of partition_map
.
val partition_map_ep :
('a -> (('b, 'c) Stdlib.Either.t, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list * 'c list, 'trace list) Stdlib.result Lwt.t
partition_map_ep
is a variant of partition_map_es
where the promises are evaluated concurrently.
val partition_map_p :
('a -> ('b, 'c) Stdlib.Either.t Lwt.t) ->
'a list ->
('b list * 'c list) Lwt.t
partition_map_p
is a variant of partition_map_s
where the promises are evaluated concurrently.
Traversal variants
val iter : ('a -> unit) -> 'a list -> unit
iter f xs
is f x0; f x1; …
.
val iter_e :
('a -> (unit, 'trace) Stdlib.result) ->
'a list ->
(unit, 'trace) Stdlib.result
iter_e
is a Result-aware variant of iter
.
val iter_s : ('a -> unit Lwt.t) -> 'a list -> unit Lwt.t
iter_s
is an Lwt-aware variant of iter
.
val iter_es :
('a -> (unit, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(unit, 'trace) Stdlib.result Lwt.t
iter_es
is an Lwt-Result-aware variant of iter
.
val iter_ep :
('a -> (unit, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(unit, 'trace list) Stdlib.result Lwt.t
iter_ep
is a variant of iter_es
where the promises are evaluated concurrently.
val iter_p : ('a -> unit Lwt.t) -> 'a list -> unit Lwt.t
iter_p
is a variant of iter_s
where the promises are evaluated concurrently.
val iteri : (int -> 'a -> unit) -> 'a list -> unit
iteri f xs
is f 0 x0; f 1 x1; …
.
val iteri_e :
(int -> 'a -> (unit, 'trace) Stdlib.result) ->
'a list ->
(unit, 'trace) Stdlib.result
iteri_e
is a Result-aware variant of iteri
.
val iteri_s : (int -> 'a -> unit Lwt.t) -> 'a list -> unit Lwt.t
iteri_s
is an Lwt-aware variant of iteri
.
val iteri_es :
(int -> 'a -> (unit, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(unit, 'trace) Stdlib.result Lwt.t
iteri_es
is an Lwt-Result-aware variant of iteri
.
val iteri_ep :
(int -> 'a -> (unit, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(unit, 'trace list) Stdlib.result Lwt.t
iteri_ep
is a variant of iteri_es
where the promises are evaluated concurrently.
val iteri_p : (int -> 'a -> unit Lwt.t) -> 'a list -> unit Lwt.t
iteri_p
is a variant of iteri_s
where the promises are evaluated concurrently.
val map : ('a -> 'b) -> 'a list -> 'b list
map f xs
is the list [f x0; f x1; …]
.
val map_e :
('a -> ('b, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.result
map_e
is a Result-aware variant of map
.
val map_s : ('a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t
map_s
is an Lwt-aware variant of map
.
val map_es :
('a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.t
map_es
is an Lwt-Result-aware variant of map
.
val map_ep :
('a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace list) Stdlib.result Lwt.t
map_ep
is a variant of map_es
where the promises are evaluated concurrently.
val map_p : ('a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t
map_p
is a variant of map_s
where the promises are evaluated concurrently.
val mapi : (int -> 'a -> 'b) -> 'a list -> 'b list
mapi f xs
is the list [f 0 x0; f 1 x1; …]
.
val mapi_e :
(int -> 'a -> ('b, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.result
mapi_e
is a Result-aware variant of mapi
.
val mapi_s : (int -> 'a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t
mapi_s
is an Lwt-aware variant of mapi
.
val mapi_es :
(int -> 'a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.t
mapi_es
is an Lwt-Result-aware variant of mapi
.
val mapi_ep :
(int -> 'a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace list) Stdlib.result Lwt.t
mapi_ep
is a variant of mapi_es
where the promises are evaluated concurrently.
val mapi_p : (int -> 'a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t
mapi_p
is a variant of mapi_s
where the promises are evaluated concurrently.
val rev_map : ('a -> 'b) -> 'a list -> 'b list
rev_map f xs
is rev @@ map f xs
but more efficient.
val rev_mapi : (int -> 'a -> 'b) -> 'a list -> 'b list
rev_mapi f xs
is rev @@ mapi f xs
but more efficient.
val rev_map_e :
('a -> ('b, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.result
rev_map_e
is a Result-aware variant of rev_map
.
val rev_map_s : ('a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t
rev_map_s
is an Lwt-aware variant of rev_map
.
val rev_map_es :
('a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.t
rev_map_es
is an Lwt-Result-aware variant of rev_map
.
val rev_map_ep :
('a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace list) Stdlib.result Lwt.t
rev_map_ep
is a variant of rev_map_es
where the promises are evaluated concurrently.
val rev_map_p : ('a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t
rev_map_p
is a variant of rev_map_s
where the promises are evaluated concurrently.
val rev_mapi_e :
(int -> 'a -> ('b, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.result
rev_mapi_e
is a Result-aware variant of rev_mapi
.
val rev_mapi_s : (int -> 'a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t
rev_mapi_s
is an Lwt-aware variant of rev_mapi
.
val rev_mapi_es :
(int -> 'a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.t
rev_mapi_es
is an Lwt-Result-aware variant of rev_mapi
.
val rev_mapi_ep :
(int -> 'a -> ('b, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace list) Stdlib.result Lwt.t
rev_mapi_ep
is a variant of rev_mapi_es
where the promises are evaluated concurrently.
val rev_mapi_p : (int -> 'a -> 'b Lwt.t) -> 'a list -> 'b list Lwt.t
rev_mapi_p
is a variant of rev_mapi_s
where the promises are evaluated concurrently.
val rev_filter_map : ('a -> 'b option) -> 'a list -> 'b list
rev_filter_map f xs
is rev @@ filter_map f xs
but more efficient.
val rev_filter_map_e :
('a -> ('b option, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.result
val filter_map_e :
('a -> ('b option, 'trace) Stdlib.result) ->
'a list ->
('b list, 'trace) Stdlib.result
filter_map_e
is a Result-aware variant of filter_map
.
val rev_filter_map_s : ('a -> 'b option Lwt.t) -> 'a list -> 'b list Lwt.t
val filter_map : ('a -> 'b option) -> 'a list -> 'b list
filter_map f xs
is filter_some @@ map f xs
but more efficient.
val filter_map_s : ('a -> 'b option Lwt.t) -> 'a list -> 'b list Lwt.t
filter_map_s
is an Lwt-aware variant of filter_map
.
val rev_filter_map_es :
('a -> ('b option, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.t
val filter_map_es :
('a -> ('b option, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace) Stdlib.result Lwt.t
filter_map_es
is an Lwt-Result-aware variant of filter_map
.
val filter_map_ep :
('a -> ('b option, 'trace) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'trace list) Stdlib.result Lwt.t
filter_map_ep
is a variant of filter_map_es
where the promises are evaluated concurrently.
val filter_map_p : ('a -> 'b option Lwt.t) -> 'a list -> 'b list Lwt.t
filter_map_p
is a variant of filter_map_s
where the promises are evaluated concurrently.
val concat_map : ('a -> 'b list) -> 'a list -> 'b list
concat_map f xs
is concat (map f xs)
but more efficient.
val concat_map_s : ('a -> 'b list Lwt.t) -> 'a list -> 'b list Lwt.t
concat_map_s
is an Lwt-aware variant of concat_map
.
val concat_map_e :
('a -> ('b list, 'error) Stdlib.result) ->
'a list ->
('b list, 'error) Stdlib.result
concat_map_e
is a Result-aware variant of concat_map
.
val concat_map_es :
('a -> ('b list, 'error) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'error) Stdlib.result Lwt.t
concat_map_es
is an Lwt-Result-aware variant of concat_map
.
val concat_map_p : ('a -> 'b list Lwt.t) -> 'a list -> 'b list Lwt.t
concat_map_p
is a variant of concat_map_s
where the promises are evaluated concurrently.
val concat_map_ep :
('a -> ('b list, 'error) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'error list) Stdlib.result Lwt.t
concat_map_ep
is a variant of concat_map_es
where the promises are evaluated concurrently.
val rev_concat_map : ('a -> 'b list) -> 'a list -> 'b list
rev_concat_map f xs
is rev (concat_map f xs)
but more efficient.
val rev_concat_map_s : ('a -> 'b list Lwt.t) -> 'a list -> 'b list Lwt.t
val rev_concat_map_e :
('a -> ('b list, 'error) Stdlib.result) ->
'a list ->
('b list, 'error) Stdlib.result
val rev_concat_map_es :
('a -> ('b list, 'error) Stdlib.result Lwt.t) ->
'a list ->
('b list, 'error) Stdlib.result Lwt.t
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
val fold_left_e :
('a -> 'b -> ('a, 'trace) Stdlib.result) ->
'a ->
'b list ->
('a, 'trace) Stdlib.result
fold_left_e
is a Result-aware variant of fold_left
.
val fold_left_s : ('a -> 'b -> 'a Lwt.t) -> 'a -> 'b list -> 'a Lwt.t
fold_left_s
is an Lwt-aware variant of fold_left
.
val fold_left_es :
('a -> 'b -> ('a, 'trace) Stdlib.result Lwt.t) ->
'a ->
'b list ->
('a, 'trace) Stdlib.result Lwt.t
fold_left_es
is an Lwt-Result-aware variant of fold_left
.
val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
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 fold_left_map_e :
('a -> 'b -> ('a * 'c, 'trace) Stdlib.result) ->
'a ->
'b list ->
('a * 'c list, 'trace) Stdlib.result
fold_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.
val fold_left_map_s :
('a -> 'b -> ('a * 'c) Lwt.t) ->
'a ->
'b list ->
('a * 'c list) Lwt.t
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.t
fold_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 : (int -> 'a -> 'b -> 'a) -> 'a -> 'b list -> 'a
val fold_left_i_e :
(int -> 'a -> 'b -> ('a, 'trace) Stdlib.result) ->
'a ->
'b list ->
('a, 'trace) Stdlib.result
val fold_left_i_s : (int -> 'a -> 'b -> 'a Lwt.t) -> 'a -> 'b list -> 'a Lwt.t
val fold_left_i_es :
(int -> 'a -> 'b -> ('a, 'trace) Stdlib.result Lwt.t) ->
'a ->
'b list ->
('a, 'trace) Stdlib.result Lwt.t
val fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b
This function is not tail-recursive
val fold_right_e :
('a -> 'b -> ('b, 'trace) Stdlib.result) ->
'a list ->
'b ->
('b, 'trace) Stdlib.result
This function is not tail-recursive
val fold_right_s : ('a -> 'b -> 'b Lwt.t) -> 'a list -> 'b -> 'b Lwt.t
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.t
This function is not tail-recursive
Double-traversal variants
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.result
val iter2_s :
when_different_lengths:'trace ->
('a -> 'b -> unit Lwt.t) ->
'a list ->
'b list ->
(unit, 'trace) Stdlib.result Lwt.t
val iter2_es :
when_different_lengths:'trace ->
('a -> 'b -> (unit, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b list ->
(unit, 'trace) Stdlib.result Lwt.t
val map2_e :
when_different_lengths:'trace ->
('a -> 'b -> ('c, 'trace) Stdlib.result) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result
val map2_s :
when_different_lengths:'trace ->
('a -> 'b -> 'c Lwt.t) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result Lwt.t
val map2_es :
when_different_lengths:'trace ->
('a -> 'b -> ('c, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result Lwt.t
val rev_map2_e :
when_different_lengths:'trace ->
('a -> 'b -> ('c, 'trace) Stdlib.result) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result
val rev_map2_s :
when_different_lengths:'trace ->
('a -> 'b -> 'c Lwt.t) ->
'a list ->
'b list ->
('c list, 'trace) Stdlib.result Lwt.t
val 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.t
val fold_left2_e :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> ('a, 'trace) Stdlib.result) ->
'a ->
'b list ->
'c list ->
('a, 'trace) Stdlib.result
val fold_left2_s :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> 'a Lwt.t) ->
'a ->
'b list ->
'c list ->
('a, 'trace) Stdlib.result Lwt.t
val 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.t
val fold_right2_e :
when_different_lengths:'trace ->
('a -> 'b -> 'c -> ('c, 'trace) Stdlib.result) ->
'a list ->
'b list ->
'c ->
('c, 'trace) Stdlib.result
This 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.t
This 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.t
This function is not tail-recursive
Scanning variants
val for_all : ('a -> bool) -> 'a list -> bool
val for_all_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
(bool, 'trace) Stdlib.result
val for_all_s : ('a -> bool Lwt.t) -> 'a list -> bool Lwt.t
val for_all_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(bool, 'trace) Stdlib.result Lwt.t
val for_all_ep :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(bool, 'trace list) Stdlib.result Lwt.t
val for_all_p : ('a -> bool Lwt.t) -> 'a list -> bool Lwt.t
val exists : ('a -> bool) -> 'a list -> bool
val exists_e :
('a -> (bool, 'trace) Stdlib.result) ->
'a list ->
(bool, 'trace) Stdlib.result
val exists_s : ('a -> bool Lwt.t) -> 'a list -> bool Lwt.t
val exists_es :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(bool, 'trace) Stdlib.result Lwt.t
val exists_ep :
('a -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
(bool, 'trace list) Stdlib.result Lwt.t
val exists_p : ('a -> bool Lwt.t) -> 'a list -> bool Lwt.t
Double-scanning variants
As 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.result
val for_all2_s :
when_different_lengths:'trace ->
('a -> 'b -> bool Lwt.t) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result Lwt.t
val for_all2_es :
when_different_lengths:'trace ->
('a -> 'b -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result Lwt.t
val exists2_e :
when_different_lengths:'trace ->
('a -> 'b -> (bool, 'trace) Stdlib.result) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result
val exists2_s :
when_different_lengths:'trace ->
('a -> 'b -> bool Lwt.t) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result Lwt.t
val exists2_es :
when_different_lengths:'trace ->
('a -> 'b -> (bool, 'trace) Stdlib.result Lwt.t) ->
'a list ->
'b list ->
(bool, 'trace) Stdlib.result Lwt.t
Combine variants
These 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.
val combine_drop : 'a list -> 'b list -> ('a * 'b) list
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)
otherwise
val combine_with_leftovers :
'a list ->
'b list ->
('a * 'b) list * ('a list, 'b list) Stdlib.Either.t option
combine_with_leftovers ll lr
is a tuple (combined, leftover)
where combined
is combine_drop ll lr
and leftover
is either Either.Left lsuffix
or Either.Right rsuffix
depending on which of ll
or lr
is longer. leftover
is None
if the two lists have the same length.
Product
val product : 'a list -> 'b list -> ('a * 'b) list
product xs ys
is the cartesian product of xs
and ys
.
In other words product xs ys
is a list containing all the pairs (x, y)
where x
is an element of xs
and y
is an element of ys
.
The order of the elements in the returned list is unspecified.
Comparison and equality
The comparison and equality functions are those of the OCaml Stdlib
.
val compare : ('a -> 'a -> int) -> 'a list -> 'a list -> int
val compare_lengths : 'a list -> 'b list -> int
val compare_length_with : 'a list -> int -> int
val equal : ('a -> 'a -> bool) -> 'a list -> 'a list -> bool
Sorting
The sorting functions are those of the OCaml Stdlib
.
val sort : ('a -> 'a -> int) -> 'a list -> 'a list
val stable_sort : ('a -> 'a -> int) -> 'a list -> 'a list
val fast_sort : ('a -> 'a -> int) -> 'a list -> 'a list
val sort_uniq : ('a -> 'a -> int) -> 'a list -> 'a list
val shuffle : rng:Stdlib.Random.State.t -> 'a list -> 'a list
shuffle l
is a list that contains the same elements as l
but in a random order.
val merge : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
merge compare xs ys
merges the lists xs
and ys
.
merge
assumes that xs
and ys
are sorted according to the order defined by compare
. If xs
and ys
are not sorted, the returned value of merge compare xs ys
is unspecified.
Assuming that xs
and ys
are sorted, merge compare xs ys
is a list
- containing all the elements of
xs
and of ys
, and - sorted according to the order defined by
compare
.
merge
is not tail-recursive.
Conversion
The conversion functions are those of the OCaml Stdlib
.
val to_seq : 'a list -> 'a Stdlib.Seq.t
val of_seq : 'a Stdlib.Seq.t -> 'a list