1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2020 Nomadic Labs <contact@nomadic-labs.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)(** {1 List}
A replacement for {!Stdlib.List} which:
- replaces the exception-raising functions by exception-safe variants,
- provides Lwt-, result- and Lwt-result-aware traversors.
[List] is intended to shadow both {!Stdlib.List} and {!Lwt_list}. *)(** {2 Basics}
Checkout {!Lwtreslib} for an introduction to the naming and semantic
convention of Lwtreslib. In a nutshell:
- Stdlib functions that raise exceptions are replaced by safe variants
(typically returning [option]).
- The [_e] suffix is for result-aware traversors ("e" stands for "error"),
[_s] and [_p] are for Lwt-aware, and [_es] and [_ep] are for
Lwt-result-aware.
- [_e], [_s], and [_es] traversors are {i fail-early}: they stop traversal
as soon as a failure ([Error] or [Fail]) occurs; [_p] and [_ep]
traversors are {i best-effort}: they only resolve once all of the
intermediate promises have, even if a failure occurs. *)(** {2 Double-traversal and combine}
Note that double-list traversors ([iter2], [map2], etc., and also [combine])
take an additional [when_different_lengths] parameter. This is to control
the error that is returned when the two lists passed as arguments have
different lengths.
This mechanism is a replacement for {!Stdlib.List.iter2} (etc.) raising
[Invalid_argument].
Note that, as per the fail-early behaviour mentioned above, [_e], [_s], and
[_es] traversors will have already processed the common-prefix before the
error is returned.
Because the best-effort behaviour of [_p] and [_ep] is unsatisfying for this
failure case, double parallel traversors are omitted from this library.
(Specifically, it is not obvious whether nor how the
[when_different_lengths] error should be composed with the other errors.)
To obtain a different behaviour for sequential traversors, or to process
two lists in parallel, you can use {!combine} or any of the alternatives
that handles the error differently: {!combine_drop},
{!combine_with_leftovers}. Finally, the {!rev_combine} is provided to allow
to avoid multiple-reversing.
{3 Special considerations}
Because they traverse the list from right-to-left, the {!fold_right2}
function and all its variants fail with [when_different_lengths] before any
of the processing starts. Whilst this is still within the fail-early
behaviour, it may be surprising enough that it requires mentioning here.
Because they may return early, {!for_all2} and {!exists2} and all their
variants may return [Ok _] even though the arguments have different lengths.
*)(** {2 API} *)moduletypeS=sig(**)(** {3 The list type} *)type'at='alist=[]|(::)of'a*'alist(** {3 Constructors and some such} *)(** [nil] is [[]] *)valnil:'alist(** [nil_e] is [Ok []] *)valnil_e:('alist,'trace)result(** [nil_s] is [Lwt.return_nil] *)valnil_s:'alistLwt.t(** [nil_es] is [Lwt.return (Ok [])] *)valnil_es:('alist,'trace)resultLwt.t(** [cons x xs] is [x :: xs] *)valcons:'a->'alist->'alist(** [is_empty xs] is [true] iff [xs] is [[]] *)valis_empty:'alist->bool(** {3 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. *)(** [hd xs] is the head (first element) of the list or [None] if the list is
empty. *)valhd:'alist->'aoption(** [tl xs] is the tail of the list (the whole list except the first element)
or [None] if the list is empty. *)valtl:'alist->'alistoption(** [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']. *)valnth:'alist->int->'aoption(** [nth_opt] is an alias for [nth] provided for compatibility with
{!Stdlib.List}. *)valnth_opt:'alist->int->'aoption(** [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]. *)vallast:'a->'alist->'a(** [last_opt xs] is the last element of the list [xs] or [None] if the list
[xs] is empty. *)vallast_opt:'alist->'aoption(** [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. *)valfind:('a->bool)->'alist->'aoption(** [find_opt] is an alias for [find] provided for compatibility with
{!Stdlib.List}. *)valfind_opt:('a->bool)->'alist->'aoption(** [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. *)valfind_map:('a->'boption)->'alist->'boption(** [mem ~equal a l] is [true] iff there is an element [e] of [l] such that
[equal a e]. *)valmem:equal:('a->'a->bool)->'a->'alist->bool(** [memq a l] is the same as [mem ~equal:Stdlib.( == ) a l]: it uses the
physical equality. *)valmemq:'a->'alist->bool(** [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. *)valassoc:equal:('a->'a->bool)->'a->('a*'b)list->'boption(** [assoc_opt] is an alias for [assoc] provided for compatibility with
{!Stdlib.List}. *)valassoc_opt:equal:('a->'a->bool)->'a->('a*'b)list->'boption(** [assq k kvs] is the same as [assoc ~equal:Stdlib.( == ) k kvs]: it uses
the physical equality. *)valassq:'a->('a*'b)list->'boption(** [assq_opt] is an alias for [assq] provided for compatibility with
{!Stdlib.List}. *)valassq_opt:'a->('a*'b)list->'boption(** [mem_assoc ~equal k l] is equivalent to
[Option.is_some @@ assoc ~equal k l]. *)valmem_assoc:equal:('a->'a->bool)->'a->('a*'b)list->bool(** [mem_assq k l] is [mem_assoc ~equal:Stdlib.( == ) k l]. *)valmem_assq:'a->('a*'b)list->bool(** [remove_assoc ~equal k l] is [l] without the first element [(k', _)] such
that [equal k k']. *)valremove_assoc:equal:('a->'a->bool)->'a->('a*'b)list->('a*'b)list(** [remove_assoq k l] is [remove_assoc ~equal:Stdlib.( == ) k l]. *)valremove_assq:'a->('a*'b)list->('a*'b)list(** {3 Initialisation} *)(** [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. *)valinit:when_negative_length:'trace->int->(int->'a)->('alist,'trace)result(** {3 Basic traversal} *)(** [length xs] is the number of elements in [xs].
[length []] is [0], [length ['x']] is [1], etc. *)vallength:'alist->int(** [rev xs] is a list with the elements appearing in the reverse order as in
[xs].
[rev ['x'; 'y']] is ['y'; 'x'] *)valrev:'alist->'alist(** [concat xs] is a list containing the elements of the elements of [xs].
[concat [['x'; 'y']; ['a'; 'b']]] is [['x'; 'y'; 'a'; 'b']] *)valconcat:'alistlist->'alist(** [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']] *)valappend:'alist->'alist->'alist(** [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]. *)valrev_append:'alist->'alist->'alist(** [flatten] is an alias for {!concat}. *)valflatten:'alistlist->'alist(** {3 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
*)(** [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. *)valcombine:when_different_lengths:'trace->'alist->'blist->(('a*'b)list,'trace)result(** [rev_combine ~when_different_lengths xs ys] is
[rev (combine ~when_different_lengths xs ys)] but more efficient. *)valrev_combine:when_different_lengths:'trace->'alist->'blist->(('a*'b)list,'trace)result(** [split xs] is [(List.map fst xs, List.map snd xs)] but more efficient. *)valsplit:('a*'b)list->'alist*'blist(** [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. *)valiter2:when_different_lengths:'trace->('a->'b->unit)->'alist->'blist->(unit,'trace)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. *)valmap2:when_different_lengths:'trace->('a->'b->'c)->'alist->'blist->('clist,'trace)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. *)valrev_map2:when_different_lengths:'trace->('a->'b->'c)->'alist->'blist->('clist,'trace)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. *)valfold_left2:when_different_lengths:'trace->('a->'b->'c->'a)->'a->'blist->'clist->('a,'trace)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. *)valfold_right2:when_different_lengths:'trace->('a->'b->'c->'c)->'alist->'blist->'c->('c,'trace)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. *)valfor_all2:when_different_lengths:'trace->('a->'b->bool)->'alist->'blist->(bool,'trace)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. *)valexists2:when_different_lengths:'trace->('a->'b->bool)->'alist->'blist->(bool,'trace)result(** {3 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}. *)(** {3 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]. *)(** [init_e] is a Result-aware variant of {!init}. *)valinit_e:when_negative_length:'trace->int->(int->('a,'trace)result)->('alist,'trace)result(** [init_s] is an Lwt-aware variant of {!init}. *)valinit_s:when_negative_length:'trace->int->(int->'aLwt.t)->('alist,'trace)resultLwt.t(** [init_es] is an Lwt-Result-aware variant of {!init}. *)valinit_es:when_negative_length:'trace->int->(int->('a,'trace)resultLwt.t)->('alist,'trace)resultLwt.t(** [init_ep] is a variant of {!init_es} where the promises are evaluated
concurrently. *)valinit_ep:when_negative_length:'error->int->(int->('a,'error)resultLwt.t)->('alist,'errorlist)resultLwt.t(** [init_p] is a variant of {!init_s} where the promises are evaluated
concurrently. *)valinit_p:when_negative_length:'trace->int->(int->'aLwt.t)->('alist,'trace)resultLwt.t(** {3 Query variants} *)(** [find_e] is a Result-aware variant of {!find}. *)valfind_e:('a->(bool,'trace)result)->'alist->('aoption,'trace)result(** [find_s] is an Lwt-aware variant of {!find}. *)valfind_s:('a->boolLwt.t)->'alist->'aoptionLwt.t(** [find_es] is an Lwt-Result-aware variant of {!find}. *)valfind_es:('a->(bool,'trace)resultLwt.t)->'alist->('aoption,'trace)resultLwt.t(** [find_map_e] is a Result-aware variant of {!find_map}. *)valfind_map_e:('a->('boption,'trace)result)->'alist->('boption,'trace)result(** [find_map_s] is an Lwt-aware variant of {!find_map}. *)valfind_map_s:('a->'boptionLwt.t)->'alist->'boptionLwt.t(** [find_map_es] is an Lwt-Result-aware variant of {!find_map}. *)valfind_map_es:('a->('boption,'trace)resultLwt.t)->'alist->('boption,'trace)resultLwt.t(** [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]] *)valfilter:('a->bool)->'alist->'alist(** [filteri] is similar to {!filter} but the predicate also receives the
element's index as an argument. *)valfilteri:(int->'a->bool)->'alist->'alist(** [find_all] is an alias for {!filter}. *)valfind_all:('a->bool)->'alist->'alist(** [rev_filter f l] is [rev (filter f l)] but more efficient. *)valrev_filter:('a->bool)->'alist->'alist(** [rev_filteri f l] is [rev (filteri f l)] but more efficient. *)valrev_filteri:(int->'a->bool)->'alist->'alist(** [rev_filter_some xs] is [rev @@ filter_some xs] but more efficient. *)valrev_filter_some:'aoptionlist->'alist(** [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']]. *)valfilter_some:'aoptionlist->'alist(** [rev_filter_ok rs] is [rev @@ filter_ok rs] but more efficient. *)valrev_filter_ok:('a,'b)resultlist->'alist(** [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']]. *)valfilter_ok:('a,'b)resultlist->'alist(** [rev_filter_error rs] is [rev @@ filter_error rs] but more efficient. *)valrev_filter_error:('a,'b)resultlist->'blist(** [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]]. *)valfilter_error:('a,'b)resultlist->'blist(** [rev_filter_left es] is [rev @@ filter_left es] but more efficient. *)valrev_filter_left:('a,'b)Either.tlist->'alist(** [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']]. *)valfilter_left:('a,'b)Either.tlist->'alist(** [rev_filter_right es] is [rev @@ filter_right es] but more efficient. *)valrev_filter_right:('a,'b)Either.tlist->'blist(** [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]]. *)valfilter_right:('a,'b)Either.tlist->'blist(** [rev_filter_e] is a Result-aware variant of {!rev_filter}. *)valrev_filter_e:('a->(bool,'trace)result)->'alist->('alist,'trace)result(** [filter_e] is a Result-aware variant of {!filter}. *)valfilter_e:('a->(bool,'trace)result)->'alist->('alist,'trace)result(** [rev_filter_s] is an Lwt-aware variant of {!rev_filter}. *)valrev_filter_s:('a->boolLwt.t)->'alist->'alistLwt.t(** [filter_s] is an Lwt-aware variant of {!filter}. *)valfilter_s:('a->boolLwt.t)->'alist->'alistLwt.t(** [rev_filter_es] is an Lwt-Result-aware variant of {!rev_filter}. *)valrev_filter_es:('a->(bool,'trace)resultLwt.t)->'alist->('alist,'trace)resultLwt.t(** [filter_es] is an Lwt-Result-aware variant of {!filter}. *)valfilter_es:('a->(bool,'trace)resultLwt.t)->'alist->('alist,'trace)resultLwt.t(** [filter_ep] is a variant of {!filter_es} where the promises are evaluated
concurrently. *)valfilter_ep:('a->(bool,'trace)resultLwt.t)->'alist->('alist,'tracelist)resultLwt.t(** [filter_p] is a variant of {!filter_s} where the promises are evaluated
concurrently. *)valfilter_p:('a->boolLwt.t)->'alist->'alistLwt.t(** [rev_filteri_e] is a Result-aware variant of {!rev_filteri}. *)valrev_filteri_e:(int->'a->(bool,'trace)result)->'alist->('alist,'trace)result(** [filteri_e] is a Result-aware variant of {!filteri}. *)valfilteri_e:(int->'a->(bool,'trace)result)->'alist->('alist,'trace)result(** [rev_filteri_s] is an Lwt-aware variant of {!rev_filteri}. *)valrev_filteri_s:(int->'a->boolLwt.t)->'alist->'alistLwt.t(** [filteri_s] is an Lwt-aware variant of {!filteri}. *)valfilteri_s:(int->'a->boolLwt.t)->'alist->'alistLwt.t(** [rev_filteri_es] is an Lwt-Result-aware variant of {!rev_filteri}. *)valrev_filteri_es:(int->'a->(bool,'trace)resultLwt.t)->'alist->('alist,'trace)resultLwt.t(** [filteri_es] is an Lwt-Result-aware variant of {!filteri}. *)valfilteri_es:(int->'a->(bool,'trace)resultLwt.t)->'alist->('alist,'trace)resultLwt.t(** [filteri_ep] is a variant of {!filteri_es} where the promises are evaluated
concurrently. *)valfilteri_ep:(int->'a->(bool,'trace)resultLwt.t)->'alist->('alist,'tracelist)resultLwt.t(** [filteri_p] is a variant of {!filteri_s} where the promises are evaluated
concurrently. *)valfilteri_p:(int->'a->boolLwt.t)->'alist->'alistLwt.t(** [rev_partition f xs] is [let rt, rf = partition f xs in (rev rt, rev rf)]
but more efficient. *)valrev_partition:('a->bool)->'alist->'alist*'alist(** [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]. *)valpartition:('a->bool)->'alist->'alist*'alist(** [rev_partition_map f xs] is
[let rt, rf = partition_map f xs in (rev rt, rev rf)]
but more efficient. *)valrev_partition_map:('a->('b,'c)Either.t)->'alist->'blist*'clist(** [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]. *)valpartition_map:('a->('b,'c)Either.t)->'alist->'blist*'clist(** [rev_partition_result rs] is [partition_result @@ rev rs] but more
efficient. *)valrev_partition_result:('a,'b)resultlist->'alist*'blist(** [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. *)valpartition_result:('a,'b)resultlist->'alist*'blist(** [rev_partition_either rs] is [partition_either @@ rev rs] but more
efficient. *)valrev_partition_either:('a,'b)Either.tlist->'alist*'blist(** [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. *)valpartition_either:('a,'b)Either.tlist->'alist*'blist(** [rev_partition_e] is a Result-aware variant of {!rev_partition}. *)valrev_partition_e:('a->(bool,'trace)result)->'alist->('alist*'alist,'trace)result(** [partition_e] is a Result-aware variant of {!partition}. *)valpartition_e:('a->(bool,'trace)result)->'alist->('alist*'alist,'trace)result(** [rev_partition_s] is an Lwt-aware variant of {!rev_partition}. *)valrev_partition_s:('a->boolLwt.t)->'alist->('alist*'alist)Lwt.t(** [partition_s] is an Lwt-aware variant of {!partition}. *)valpartition_s:('a->boolLwt.t)->'alist->('alist*'alist)Lwt.t(** [rev_partition_es] is an Lwt-Result-aware variant of {!rev_partition}. *)valrev_partition_es:('a->(bool,'trace)resultLwt.t)->'alist->('alist*'alist,'trace)resultLwt.t(** [partition_es] is an Lwt-Result-aware variant of {!partition}. *)valpartition_es:('a->(bool,'trace)resultLwt.t)->'alist->('alist*'alist,'trace)resultLwt.t(** [partition_ep] is a variant of {!partition_es} where the promises are
evaluated concurrently. *)valpartition_ep:('a->(bool,'trace)resultLwt.t)->'alist->('alist*'alist,'tracelist)resultLwt.t(** [partition_p] is a variant of {!partition_s} where the promises are
evaluated concurrently. *)valpartition_p:('a->boolLwt.t)->'alist->('alist*'alist)Lwt.t(** [rev_partition_map_e] is a Result-aware variant of {!rev_partition_map}. *)valrev_partition_map_e:('a->(('b,'c)Either.t,'trace)result)->'alist->('blist*'clist,'trace)result(** [partition_map_e] is a Result-aware variant of {!partition_map}. *)valpartition_map_e:('a->(('b,'c)Either.t,'trace)result)->'alist->('blist*'clist,'trace)result(** [rev_partition_map_s] is an Lwt-aware variant of {!rev_partition_map}. *)valrev_partition_map_s:('a->('b,'c)Either.tLwt.t)->'alist->('blist*'clist)Lwt.t(** [partition_map_s] is an Lwt-aware variant of {!partition_map}. *)valpartition_map_s:('a->('b,'c)Either.tLwt.t)->'alist->('blist*'clist)Lwt.t(** [rev_partition_map_es] is an Lwt-Result-aware variant of
{!rev_partition_map}. *)valrev_partition_map_es:('a->(('b,'c)Either.t,'trace)resultLwt.t)->'alist->('blist*'clist,'trace)resultLwt.t(** [partition_map_es] is an Lwt-Result-aware variant of {!partition_map}. *)valpartition_map_es:('a->(('b,'c)Either.t,'trace)resultLwt.t)->'alist->('blist*'clist,'trace)resultLwt.t(** [partition_map_ep] is a variant of {!partition_map_es} where the promises are
evaluated concurrently. *)valpartition_map_ep:('a->(('b,'c)Either.t,'trace)resultLwt.t)->'alist->('blist*'clist,'tracelist)resultLwt.t(** [partition_map_p] is a variant of {!partition_map_s} where the promises are
evaluated concurrently. *)valpartition_map_p:('a->('b,'c)Either.tLwt.t)->'alist->('blist*'clist)Lwt.t(** {3 Traversal variants} *)(** [iter f xs] is [f x0; f x1; …]. *)valiter:('a->unit)->'alist->unit(** [iter_e] is a Result-aware variant of {!iter}. *)valiter_e:('a->(unit,'trace)result)->'alist->(unit,'trace)result(** [iter_s] is an Lwt-aware variant of {!iter}. *)valiter_s:('a->unitLwt.t)->'alist->unitLwt.t(** [iter_es] is an Lwt-Result-aware variant of {!iter}. *)valiter_es:('a->(unit,'trace)resultLwt.t)->'alist->(unit,'trace)resultLwt.t(** [iter_ep] is a variant of {!iter_es} where the promises are evaluated
concurrently. *)valiter_ep:('a->(unit,'trace)resultLwt.t)->'alist->(unit,'tracelist)resultLwt.t(** [iter_p] is a variant of {!iter_s} where the promises are evaluated
concurrently. *)valiter_p:('a->unitLwt.t)->'alist->unitLwt.t(** [iteri f xs] is [f 0 x0; f 1 x1; …]. *)valiteri:(int->'a->unit)->'alist->unit(** [iteri_e] is a Result-aware variant of {!iteri}. *)valiteri_e:(int->'a->(unit,'trace)result)->'alist->(unit,'trace)result(** [iteri_s] is an Lwt-aware variant of {!iteri}. *)valiteri_s:(int->'a->unitLwt.t)->'alist->unitLwt.t(** [iteri_es] is an Lwt-Result-aware variant of {!iteri}. *)valiteri_es:(int->'a->(unit,'trace)resultLwt.t)->'alist->(unit,'trace)resultLwt.t(** [iteri_ep] is a variant of {!iteri_es} where the promises are evaluated
concurrently. *)valiteri_ep:(int->'a->(unit,'trace)resultLwt.t)->'alist->(unit,'tracelist)resultLwt.t(** [iteri_p] is a variant of {!iteri_s} where the promises are evaluated
concurrently. *)valiteri_p:(int->'a->unitLwt.t)->'alist->unitLwt.t(** [map f xs] is the list [[f x0; f x1; …]]. *)valmap:('a->'b)->'alist->'blist(** [map_e] is a Result-aware variant of {!map}. *)valmap_e:('a->('b,'trace)result)->'alist->('blist,'trace)result(** [map_s] is an Lwt-aware variant of {!map}. *)valmap_s:('a->'bLwt.t)->'alist->'blistLwt.t(** [map_es] is an Lwt-Result-aware variant of {!map}. *)valmap_es:('a->('b,'trace)resultLwt.t)->'alist->('blist,'trace)resultLwt.t(** [map_ep] is a variant of {!map_es} where the promises are evaluated
concurrently. *)valmap_ep:('a->('b,'trace)resultLwt.t)->'alist->('blist,'tracelist)resultLwt.t(** [map_p] is a variant of {!map_s} where the promises are evaluated
concurrently. *)valmap_p:('a->'bLwt.t)->'alist->'blistLwt.t(** [mapi f xs] is the list [[f 0 x0; f 1 x1; …]]. *)valmapi:(int->'a->'b)->'alist->'blist(** [mapi_e] is a Result-aware variant of {!mapi}. *)valmapi_e:(int->'a->('b,'trace)result)->'alist->('blist,'trace)result(** [mapi_s] is an Lwt-aware variant of {!mapi}. *)valmapi_s:(int->'a->'bLwt.t)->'alist->'blistLwt.t(** [mapi_es] is an Lwt-Result-aware variant of {!mapi}. *)valmapi_es:(int->'a->('b,'trace)resultLwt.t)->'alist->('blist,'trace)resultLwt.t(** [mapi_ep] is a variant of {!mapi_es} where the promises are evaluated
concurrently. *)valmapi_ep:(int->'a->('b,'trace)resultLwt.t)->'alist->('blist,'tracelist)resultLwt.t(** [mapi_p] is a variant of {!mapi_s} where the promises are evaluated
concurrently. *)valmapi_p:(int->'a->'bLwt.t)->'alist->'blistLwt.t(** [rev_map f xs] is [rev @@ map f xs] but more efficient. *)valrev_map:('a->'b)->'alist->'blist(** [rev_mapi f xs] is [rev @@ mapi f xs] but more efficient. *)valrev_mapi:(int->'a->'b)->'alist->'blist(** [rev_map_e] is a Result-aware variant of {!rev_map}. *)valrev_map_e:('a->('b,'trace)result)->'alist->('blist,'trace)result(** [rev_map_s] is an Lwt-aware variant of {!rev_map}. *)valrev_map_s:('a->'bLwt.t)->'alist->'blistLwt.t(** [rev_map_es] is an Lwt-Result-aware variant of {!rev_map}. *)valrev_map_es:('a->('b,'trace)resultLwt.t)->'alist->('blist,'trace)resultLwt.t(** [rev_map_ep] is a variant of {!rev_map_es} where the promises are
evaluated concurrently. *)valrev_map_ep:('a->('b,'trace)resultLwt.t)->'alist->('blist,'tracelist)resultLwt.t(** [rev_map_p] is a variant of {!rev_map_s} where the promises are evaluated
concurrently. *)valrev_map_p:('a->'bLwt.t)->'alist->'blistLwt.t(** [rev_mapi_e] is a Result-aware variant of {!rev_mapi}. *)valrev_mapi_e:(int->'a->('b,'trace)result)->'alist->('blist,'trace)result(** [rev_mapi_s] is an Lwt-aware variant of {!rev_mapi}. *)valrev_mapi_s:(int->'a->'bLwt.t)->'alist->'blistLwt.t(** [rev_mapi_es] is an Lwt-Result-aware variant of {!rev_mapi}. *)valrev_mapi_es:(int->'a->('b,'trace)resultLwt.t)->'alist->('blist,'trace)resultLwt.t(** [rev_mapi_ep] is a variant of {!rev_mapi_es} where the promises are
evaluated concurrently. *)valrev_mapi_ep:(int->'a->('b,'trace)resultLwt.t)->'alist->('blist,'tracelist)resultLwt.t(** [rev_mapi_p] is a variant of {!rev_mapi_s} where the promises are
evaluated concurrently. *)valrev_mapi_p:(int->'a->'bLwt.t)->'alist->'blistLwt.t(** [rev_filter_map f xs] is [rev @@ filter_map f xs] but more efficient. *)valrev_filter_map:('a->'boption)->'alist->'blist(** [rev_filter_map_e] is a Result-aware variant of {!rev_filter_map}. *)valrev_filter_map_e:('a->('boption,'trace)result)->'alist->('blist,'trace)result(** [filter_map_e] is a Result-aware variant of {!filter_map}. *)valfilter_map_e:('a->('boption,'trace)result)->'alist->('blist,'trace)result(** [rev_filter_map_s] is an Lwt-aware variant of {!rev_filter_map}. *)valrev_filter_map_s:('a->'boptionLwt.t)->'alist->'blistLwt.t(** [filter_map f xs] is [filter_some @@ map f xs] but more efficient. *)valfilter_map:('a->'boption)->'alist->'blist(** [filter_map_s] is an Lwt-aware variant of {!filter_map}. *)valfilter_map_s:('a->'boptionLwt.t)->'alist->'blistLwt.t(** [rev_filter_map_es] is an Lwt-Result-aware variant of {!rev_filter_map}. *)valrev_filter_map_es:('a->('boption,'trace)resultLwt.t)->'alist->('blist,'trace)resultLwt.t(** [filter_map_es] is an Lwt-Result-aware variant of {!filter_map}. *)valfilter_map_es:('a->('boption,'trace)resultLwt.t)->'alist->('blist,'trace)resultLwt.t(** [filter_map_ep] is a variant of {!filter_map_es} where the promises are evaluated concurrently. *)valfilter_map_ep:('a->('boption,'trace)resultLwt.t)->'alist->('blist,'tracelist)resultLwt.t(** [filter_map_p] is a variant of {!filter_map_s} where the promises are evaluated concurrently. *)valfilter_map_p:('a->'boptionLwt.t)->'alist->'blistLwt.t(** [concat_map f xs] is [concat (map f xs)] but more efficient. *)valconcat_map:('a->'blist)->'alist->'blist(** [concat_map_s] is an Lwt-aware variant of {!concat_map}. *)valconcat_map_s:('a->'blistLwt.t)->'alist->'blistLwt.t(** [concat_map_e] is a Result-aware variant of {!concat_map}. *)valconcat_map_e:('a->('blist,'error)result)->'alist->('blist,'error)result(** [concat_map_es] is an Lwt-Result-aware variant of {!concat_map}. *)valconcat_map_es:('a->('blist,'error)resultLwt.t)->'alist->('blist,'error)resultLwt.t(** [concat_map_p] is a variant of {!concat_map_s} where the promises are evaluated concurrently. *)valconcat_map_p:('a->'blistLwt.t)->'alist->'blistLwt.t(** [concat_map_ep] is a variant of {!concat_map_es} where the promises are evaluated concurrently. *)valconcat_map_ep:('a->('blist,'error)resultLwt.t)->'alist->('blist,'errorlist)resultLwt.t(** [rev_concat_map f xs] is [rev (concat_map f xs)] but more efficient.*)valrev_concat_map:('a->'blist)->'alist->'blist(** [rev_concat_map_s] is an Lwt-aware variant of {!rev_concat_map}. *)valrev_concat_map_s:('a->'blistLwt.t)->'alist->'blistLwt.t(** [rev_concat_map_e] is a Result-aware variant of {!rev_concat_map}. *)valrev_concat_map_e:('a->('blist,'error)result)->'alist->('blist,'error)result(** [rev_concat_map_es] is an Lwt-Result-aware variant of {!rev_concat_map}. *)valrev_concat_map_es:('a->('blist,'error)resultLwt.t)->'alist->('blist,'error)resultLwt.tvalfold_left:('a->'b->'a)->'a->'blist->'a(** [fold_left_e] is a Result-aware variant of {!fold_left}. *)valfold_left_e:('a->'b->('a,'trace)result)->'a->'blist->('a,'trace)result(** [fold_left_s] is an Lwt-aware variant of {!fold_left}. *)valfold_left_s:('a->'b->'aLwt.t)->'a->'blist->'aLwt.t(** [fold_left_es] is an Lwt-Result-aware variant of {!fold_left}. *)valfold_left_es:('a->'b->('a,'trace)resultLwt.t)->'a->'blist->('a,'trace)resultLwt.t(** [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]. *)valfold_left_map:('a->'b->'a*'c)->'a->'blist->'a*'clist(** [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. *)valfold_left_map_e:('a->'b->('a*'c,'trace)result)->'a->'blist->('a*'clist,'trace)result(** [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]. *)valfold_left_map_s:('a->'b->('a*'c)Lwt.t)->'a->'blist->('a*'clist)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. *)valfold_left_map_es:('a->'b->('a*'c,'trace)resultLwt.t)->'a->'blist->('a*'clist,'trace)resultLwt.tvalfold_left_i:(int->'a->'b->'a)->'a->'blist->'avalfold_left_i_e:(int->'a->'b->('a,'trace)result)->'a->'blist->('a,'trace)resultvalfold_left_i_s:(int->'a->'b->'aLwt.t)->'a->'blist->'aLwt.tvalfold_left_i_es:(int->'a->'b->('a,'trace)resultLwt.t)->'a->'blist->('a,'trace)resultLwt.t(** This function is not tail-recursive *)valfold_right:('a->'b->'b)->'alist->'b->'b(** This function is not tail-recursive *)valfold_right_e:('a->'b->('b,'trace)result)->'alist->'b->('b,'trace)result(** This function is not tail-recursive *)valfold_right_s:('a->'b->'bLwt.t)->'alist->'b->'bLwt.t(** This function is not tail-recursive *)valfold_right_es:('a->'b->('b,'trace)resultLwt.t)->'alist->'b->('b,'trace)resultLwt.t(** {3 Double-traversal variants}
As mentioned above, there are no [_p] and [_ep] double-traversors. Use
{!combine} (and variants) to circumvent this. *)valiter2_e:when_different_lengths:'trace->('a->'b->(unit,'trace)result)->'alist->'blist->(unit,'trace)resultvaliter2_s:when_different_lengths:'trace->('a->'b->unitLwt.t)->'alist->'blist->(unit,'trace)resultLwt.tvaliter2_es:when_different_lengths:'trace->('a->'b->(unit,'trace)resultLwt.t)->'alist->'blist->(unit,'trace)resultLwt.tvalmap2_e:when_different_lengths:'trace->('a->'b->('c,'trace)result)->'alist->'blist->('clist,'trace)resultvalmap2_s:when_different_lengths:'trace->('a->'b->'cLwt.t)->'alist->'blist->('clist,'trace)resultLwt.tvalmap2_es:when_different_lengths:'trace->('a->'b->('c,'trace)resultLwt.t)->'alist->'blist->('clist,'trace)resultLwt.tvalrev_map2_e:when_different_lengths:'trace->('a->'b->('c,'trace)result)->'alist->'blist->('clist,'trace)resultvalrev_map2_s:when_different_lengths:'trace->('a->'b->'cLwt.t)->'alist->'blist->('clist,'trace)resultLwt.tvalrev_map2_es:when_different_lengths:'trace->('a->'b->('c,'trace)resultLwt.t)->'alist->'blist->('clist,'trace)resultLwt.tvalfold_left2_e:when_different_lengths:'trace->('a->'b->'c->('a,'trace)result)->'a->'blist->'clist->('a,'trace)resultvalfold_left2_s:when_different_lengths:'trace->('a->'b->'c->'aLwt.t)->'a->'blist->'clist->('a,'trace)resultLwt.tvalfold_left2_es:when_different_lengths:'trace->('a->'b->'c->('a,'trace)resultLwt.t)->'a->'blist->'clist->('a,'trace)resultLwt.t(** This function is not tail-recursive *)valfold_right2_e:when_different_lengths:'trace->('a->'b->'c->('c,'trace)result)->'alist->'blist->'c->('c,'trace)result(** This function is not tail-recursive *)valfold_right2_s:when_different_lengths:'trace->('a->'b->'c->'cLwt.t)->'alist->'blist->'c->('c,'trace)resultLwt.t(** This function is not tail-recursive *)valfold_right2_es:when_different_lengths:'trace->('a->'b->'c->('c,'trace)resultLwt.t)->'alist->'blist->'c->('c,'trace)resultLwt.t(** {3 Scanning variants} *)valfor_all:('a->bool)->'alist->boolvalfor_all_e:('a->(bool,'trace)result)->'alist->(bool,'trace)resultvalfor_all_s:('a->boolLwt.t)->'alist->boolLwt.tvalfor_all_es:('a->(bool,'trace)resultLwt.t)->'alist->(bool,'trace)resultLwt.tvalfor_all_ep:('a->(bool,'trace)resultLwt.t)->'alist->(bool,'tracelist)resultLwt.tvalfor_all_p:('a->boolLwt.t)->'alist->boolLwt.tvalexists:('a->bool)->'alist->boolvalexists_e:('a->(bool,'trace)result)->'alist->(bool,'trace)resultvalexists_s:('a->boolLwt.t)->'alist->boolLwt.tvalexists_es:('a->(bool,'trace)resultLwt.t)->'alist->(bool,'trace)resultLwt.tvalexists_ep:('a->(bool,'trace)resultLwt.t)->'alist->(bool,'tracelist)resultLwt.tvalexists_p:('a->boolLwt.t)->'alist->boolLwt.t(** {3 Double-scanning variants}
As mentioned above, there are no [_p] and [_ep] double-scanners. Use
{!combine} (and variants) to circumvent this. *)valfor_all2_e:when_different_lengths:'trace->('a->'b->(bool,'trace)result)->'alist->'blist->(bool,'trace)resultvalfor_all2_s:when_different_lengths:'trace->('a->'b->boolLwt.t)->'alist->'blist->(bool,'trace)resultLwt.tvalfor_all2_es:when_different_lengths:'trace->('a->'b->(bool,'trace)resultLwt.t)->'alist->'blist->(bool,'trace)resultLwt.tvalexists2_e:when_different_lengths:'trace->('a->'b->(bool,'trace)result)->'alist->'blist->(bool,'trace)resultvalexists2_s:when_different_lengths:'trace->('a->'b->boolLwt.t)->'alist->'blist->(bool,'trace)resultLwt.tvalexists2_es:when_different_lengths:'trace->('a->'b->(bool,'trace)resultLwt.t)->'alist->'blist->(bool,'trace)resultLwt.t(** {3 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. *)(** [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
*)valcombine_drop:'alist->'blist->('a*'b)list(** [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. *)valcombine_with_leftovers:'alist->'blist->('a*'b)list*('alist,'blist)Either.toption(** {3 Product} *)(** [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. *)valproduct:'alist->'blist->('a*'b)list(** {3 Comparison and equality}
The comparison and equality functions are those of the OCaml [Stdlib]. *)valcompare:('a->'a->int)->'alist->'alist->intvalcompare_lengths:'alist->'blist->intvalcompare_length_with:'alist->int->intvalequal:('a->'a->bool)->'alist->'alist->bool(** {3 Sorting}
The sorting functions are those of the OCaml [Stdlib]. *)valsort:('a->'a->int)->'alist->'alistvalstable_sort:('a->'a->int)->'alist->'alistvalfast_sort:('a->'a->int)->'alist->'alistvalsort_uniq:('a->'a->int)->'alist->'alist(** [shuffle l] is a list that contains the same elements as [l] but in a
random order. *)valshuffle:rng:Random.State.t->'alist->'alist(** [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. *)valmerge:('a->'a->int)->'alist->'alist->'alist(** {3 Conversion}
The conversion functions are those of the OCaml [Stdlib]. *)valto_seq:'alist->'aStdlib.Seq.tvalof_seq:'aStdlib.Seq.t->'alistend