Core_kernel.List
This module extends Base.List
with bin_io and quickcheck.
include module type of struct include Base.List end
val hash_fold_t : (Base.Hash.state -> 'a -> Base.Hash.state) -> Base.Hash.state -> 'a list -> Base.Hash.state
include Base.Sexpable.S1 with type 'a t := 'a list
val t_of_sexp : (Sexplib0.Sexp.t -> 'a) -> Sexplib0.Sexp.t -> 'a list
val sexp_of_t : ('a -> Sexplib0.Sexp.t) -> 'a list -> Sexplib0.Sexp.t
val t_sexp_grammar : Base.Sexp.Private.Raw_grammar.t
include Base.Container.S1 with type 'a t := 'a list
Checks whether the provided element is there, using equal
.
fold t ~init ~f
returns f (... f (f (f init e1) e2) e3 ...) en
, where e1..en
are the elements of t
val fold_result : 'a list -> init:'accum -> f:('accum -> 'a -> ('accum, 'e) Base.Result.t) ->
('accum, 'e) Base.Result.t
fold_result t ~init ~f
is a short-circuiting version of fold
that runs in the Result
monad. If f
returns an Error _
, that value is returned without any additional invocations of f
.
val fold_until : 'a list -> init:'accum -> f:('accum -> 'a -> ('accum, 'final) Base__Container_intf.Export.Continue_or_stop.t) ->
finish:('accum -> 'final) -> 'final
fold_until t ~init ~f ~finish
is a short-circuiting version of fold
. If f
returns Stop _
the computation ceases and results in that value. If f
returns Continue _
, the fold will proceed. If f
never returns Stop _
, the final result is computed by finish
.
Example:
type maybe_negative =
| Found_negative of int
| All_nonnegative of { sum : int }
(** [first_neg_or_sum list] returns the first negative number in [list], if any,
otherwise returns the sum of the list. *)
let first_neg_or_sum =
List.fold_until ~init:0
~f:(fun sum x ->
if x < 0
then Stop (Found_negative x)
else Continue (sum + x))
~finish:(fun sum -> All_nonnegative { sum })
;;
let x = first_neg_or_sum [1; 2; 3; 4; 5]
val x : maybe_negative = All_nonnegative {sum = 15}
let y = first_neg_or_sum [1; 2; -3; 4; 5]
val y : maybe_negative = Found_negative -3
Returns true
if and only if there exists an element for which the provided function evaluates to true
. This is a short-circuiting operation.
Returns true
if and only if the provided function evaluates to true
for all elements. This is a short-circuiting operation.
val sum : (module Base__Container_intf.Summable with type t = 'sum) -> 'a list -> f:('a -> 'sum) -> 'sum
Returns the sum of f i
for all i
in the container.
Returns as an option
the first element for which f
evaluates to true.
Returns the first evaluation of f
that returns Some
, and returns None
if there is no such element.
Returns a minimum (resp maximum) element from the collection using the provided compare
function, or None
if the collection is empty. In case of a tie, the first element encountered while traversing the collection is returned. The implementation uses fold
so it has the same complexity as fold
.
include Base.Monad.S with type 'a t := 'a list
t >>= f
returns a computation that sequences the computations represented by two monad elements. The resulting computation first does t
to yield a value v
, and then runs the computation returned by f v
.
module Monad_infix : sig ... end
ignore_m t
is map t ~f:(fun _ -> ())
. ignore_m
used to be called ignore
, but we decided that was a bad name, because it shadowed the widely used Caml.ignore
. Some monads still do let ignore = ignore_m
for historical reasons.
module Let_syntax : sig ... end
These are convenient to have in scope when programming with a monad:
module Or_unequal_lengths : sig ... end
Or_unequal_lengths
is used for functions that take multiple lists and that only make sense if all the lists have the same length, e.g., iter2
, map3
. Such functions check the list lengths prior to doing anything else, and return Unequal_lengths
if not all the lists have the same length.
of_list
is the identity function. It is useful so that the List
module matches the same signature that other container modules do, namely:
val of_list : 'a List.t -> 'a t
Return the n
-th element of the given list. The first element (head of the list) is at position 0. Raise if the list is too short or n
is negative.
rev_append l1 l2
reverses l1
and concatenates it to l2
. This is equivalent to (
List.rev
l1) @ l2
, but rev_append
is more efficient.
unordered_append l1 l2
has the same elements as l1 @ l2
, but in some unspecified order. Generally takes time proportional to length of first list, but is O(1) if either list is empty.
rev_map l ~f
gives the same result as List.rev
(
ListLabels.map
f l)
, but is more efficient.
iter2 [a1; ...; an] [b1; ...; bn] ~f
calls in turn f a1 b1; ...; f an bn
. The exn version will raise if the two lists have different lengths.
val iter2 : 'a list -> 'b list -> f:('a -> 'b -> unit) -> unit Or_unequal_lengths.t
rev_map2_exn l1 l2 ~f
gives the same result as List.rev (List.map2_exn l1 l2
~f)
, but is more efficient.
val rev_map2 : 'a list -> 'b list -> f:('a -> 'b -> 'c) -> 'c list Or_unequal_lengths.t
fold2 ~f ~init:a [b1; ...; bn] [c1; ...; cn]
is f (... (f (f a b1 c1) b2 c2)
...) bn cn
. The exn version will raise if the two lists have different lengths.
val fold2 : 'a list -> 'b list -> init:'c -> f:('c -> 'a -> 'b -> 'c) -> 'c Or_unequal_lengths.t
Like List.for_all
, but passes the index as an argument.
Like List.for_all
, but for a two-argument predicate. The exn version will raise if the two lists have different lengths.
val for_all2 : 'a list -> 'b list -> f:('a -> 'b -> bool) -> bool Or_unequal_lengths.t
Like List.exists
, but passes the index as an argument.
Like List.exists
, but for a two-argument predicate. The exn version will raise if the two lists have different lengths.
val exists2 : 'a list -> 'b list -> f:('a -> 'b -> bool) -> bool Or_unequal_lengths.t
filter l ~f
returns all the elements of the list l
that satisfy the predicate f
. The order of the elements in the input list is preserved.
Like filter
, but reverses the order of the input list.
partition_map t ~f
partitions t
according to f
.
partition_tf l ~f
returns a pair of lists (l1, l2)
, where l1
is the list of all the elements of l
that satisfy the predicate p
, and l2
is the list of all the elements of l
that do not satisfy p
. The order of the elements in the input list is preserved. The "tf" suffix is mnemonic to remind readers at a call that the result is (trues, falses).
val partition_result : ('ok, 'error) Base.Result.t list -> 'ok list * 'error list
partition_result l
returns a pair of lists (l1, l2)
, where l1
is the list of all Ok
elements in l
and l2
is the list of all Error
elements. The order of elements in the input list is preserved.
split_n [e1; ...; em] n
is ([e1; ...; en], [en+1; ...; em])
.
n > m
, ([e1; ...; em], [])
is returned.n < 0
, ([], [e1; ...; em])
is returned.Sort a list in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see Array.sort
for a complete specification). For example, Poly.compare
is a suitable comparison function.
The current implementation uses Merge Sort. It runs in linear heap space and logarithmic stack space.
Presently, the sort is stable, meaning that two equal elements in the input will be in the same order in the output.
Like sort
, but guaranteed to be stable.
Merges two lists: assuming that l1
and l2
are sorted according to the comparison function compare
, merge compare l1 l2
will return a sorted list containing all the elements of l1
and l2
. If several elements compare equal, the elements of l1
will be before the elements of l2
.
Returns the given list without its first element. Raises if the list is empty.
find_exn t ~f
returns the first element of t
that satisfies f
. It raises Caml.Not_found
or Not_found_s
if there is no such element.
Returns the first evaluation of f
that returns Some
. Raises Caml.Not_found
or Not_found_s
if f
always returns None
.
Like find_map
and find_map_exn
, but passes the index as an argument.
map f [a1; ...; an]
applies function f
to a1
, a2
, ..., an
, in order, and builds the list [f a1; ...; f an]
with the results returned by f
.
folding_map
is a version of map
that threads an accumulator through calls to f
.
fold_map
is a combination of fold
and map
that threads an accumulator through calls to f
.
concat_map t ~f
is concat (map t ~f)
, except that there is no guarantee about the order in which f
is applied to the elements of t
.
concat_mapi t ~f
is like concat_map, but passes the index as an argument
map2 [a1; ...; an] [b1; ...; bn] ~f
is [f a1 b1; ...; f an bn]
. The exn version will raise if the two lists have different lengths.
val map2 : 'a list -> 'b list -> f:('a -> 'b -> 'c) -> 'c list Or_unequal_lengths.t
Analogous to rev_map2
.
val rev_map3 : 'a list -> 'b list -> 'c list -> f:('a -> 'b -> 'c -> 'd) -> 'd list Or_unequal_lengths.t
Analogous to map2
.
val map3 : 'a list -> 'b list -> 'c list -> f:('a -> 'b -> 'c -> 'd) -> 'd list Or_unequal_lengths.t
rev_map_append l1 l2 ~f
reverses l1
mapping f
over each element, and appends the result to the front of l2
.
fold_right [a1; ...; an] ~f ~init:b
is f a1 (f a2 (... (f an b) ...))
.
fold_left
is the same as Container.S1.fold
, and one should always use fold
rather than fold_left
, except in functors that are parameterized over a more general signature where this equivalence does not hold.
Transform a list of pairs into a pair of lists: unzip [(a1,b1); ...; (an,bn)]
is ([a1; ...; an], [b1; ...; bn])
.
Transform a pair of lists into an (optional) list of pairs: zip [a1; ...; an] [b1;
...; bn]
is [(a1,b1); ...; (an,bn)]
. Returns Unequal_lengths
if the two lists have different lengths.
val zip : 'a list -> 'b list -> ('a * 'b) list Or_unequal_lengths.t
mapi
is just like map, but it also passes in the index of each element as the first argument to the mapped function. Tail-recursive.
iteri
is just like iter
, but it also passes in the index of each element as the first argument to the iter'd function. Tail-recursive.
foldi
is just like fold
, but it also passes in the index of each element as the first argument to the folded function. Tail-recursive.
reduce_exn [a1; ...; an] ~f
is f (... (f (f a1 a2) a3) ...) an
. It fails on the empty list. Tail recursive.
reduce_balanced
returns the same value as reduce
when f
is associative, but differs in that the tree of nested applications of f
has logarithmic depth.
This is useful when your 'a
grows in size as you reduce it and f
becomes more expensive with bigger inputs. For example, reduce_balanced ~f:(^)
takes n*log(n)
time, while reduce ~f:(^)
takes quadratic time.
group l ~break
returns a list of lists (i.e., groups) whose concatenation is equal to the original list. Each group is broken where break
returns true on a pair of successive elements.
Example:
group ~break:(<>) ['M';'i';'s';'s';'i';'s';'s';'i';'p';'p';'i'] ->
[['M'];['i'];['s';'s'];['i'];['s';'s'];['i'];['p';'p'];['i']]
This is just like group
, except that you get the index in the original list of the current element along with the two elements.
Example, group the chars of "Mississippi"
into triples:
groupi ~break:(fun i _ _ -> i mod 3 = 0)
['M';'i';'s';'s';'i';'s';'s';'i';'p';'p';'i'] ->
[['M'; 'i'; 's']; ['s'; 'i'; 's']; ['s'; 'i'; 'p']; ['p'; 'i']]
chunks_of l ~length
returns a list of lists whose concatenation is equal to the original list. Every list has length
elements, except for possibly the last list, which may have fewer. chunks_of
raises if length <= 0
.
The final element of a list. The _exn
version raises on the empty list.
is_prefix xs ~prefix
returns true
if xs
starts with prefix
.
is_suffix xs ~suffix
returns true
if xs
ends with suffix
.
find_consecutive_duplicate t ~equal
returns the first pair of consecutive elements (a1, a2)
in t
such that equal a1 a2
. They are returned in the same order as they appear in t
. equal
need not be an equivalence relation; it is simply used as a predicate on consecutive elements.
val remove_consecutive_duplicates : ?which_to_keep:[ `First | `Last ] ->
'a list -> equal:('a -> 'a -> bool) -> 'a list
Returns the given list with consecutive duplicates removed. The relative order of the other elements is unaffected. The element kept from a run of duplicates is determined by which_to_keep
.
Returns the given list with duplicates removed and in sorted order.
find_a_dup
returns a duplicate from the list (with no guarantees about which duplicate you get), or None
if there are no dups.
Returns true if there are any two elements in the list which are the same. O(n log n) time complexity.
find_all_dups
returns a list of all elements that occur more than once, with no guarantees about order. O(n log n) time complexity.
count l ~f
is the number of elements in l
that satisfy the predicate f
.
val range : ?stride:int -> ?start:[ `inclusive | `exclusive ] ->
?stop:[ `inclusive | `exclusive ] -> int -> int -> int list
range ?stride ?start ?stop start_i stop_i
is the list of integers from start_i
to stop_i
, stepping by stride
. If stride
< 0 then we need start_i
> stop_i
for the result to be nonempty (or start_i
= stop_i
in the case where both bounds are inclusive).
val range' : compare:('a -> 'a -> int) -> stride:('a -> 'a) ->
?start:[ `inclusive | `exclusive ] -> ?stop:[ `inclusive | `exclusive ] ->
'a -> 'a -> 'a list
range'
is analogous to range
for general start/stop/stride types. range'
raises if stride x
returns x
or if the direction that stride x
moves x
changes from one call to the next.
init n ~f
is [(f 0); (f 1); ...; (f (n-1))]
. It is an error if n < 0
. init
applies f
to values in decreasing order; starting with n - 1
, and ending with 0
. This is the opposite order to Array.init
.
rev_filter_map l ~f
is the reversed sublist of l
containing only elements for which f
returns Some e
.
rev_filter_mapi is just like rev_filter_map
, but it also passes in the index of each element as the first argument to the mapped function. Tail-recursive.
filter_map l ~f
is the sublist of l
containing only elements for which f
returns Some e
.
filter_mapi is just like filter_map
, but it also passes in the index of each element as the first argument to the mapped function. Tail-recursive.
filter_opt l
is the sublist of l
containing only elements which are Some e
. In other words, filter_opt l
= filter_map ~f:Fn.id l
.
sub pos len l
is the len
-element sublist of l
, starting at pos
.
take l n
returns the first n
elements of l
, or all of l
if n > length l
. take l n = fst (split_n l n)
.
drop l n
returns l
without the first n
elements, or the empty list if n >
length l
. drop l n
is equivalent to snd (split_n l n)
.
take_while l ~f
returns the longest prefix of l
for which f
is true
.
drop_while l ~f
drops the longest prefix of l
for which f
is true
.
split_while xs ~f = (take_while xs ~f, drop_while xs ~f)
.
drop_last l
drops the last element of l
, returning None
if l
is empty
.
Concatenates a list of lists. The elements of the argument are all concatenated together (in the same order) to give the result. Tail recursive over outer and inner lists.
Like concat
, but faster and without preserving any ordering (i.e., for lists that are essentially viewed as multi-sets).
Returns a list with all possible pairs -- if the input lists have length len1
and len2
, the resulting list will have length len1 * len2
.
val permute : ?random_state:Base.Random.State.t -> 'a list -> 'a list
permute ?random_state t
returns a permutation of t
.
permute
side-effects random_state
by repeated calls to Random.State.int
. If random_state
is not supplied, permute
uses Random.State.default
.
val random_element : ?random_state:Base.Random.State.t -> 'a list -> 'a option
random_element ?random_state t
is None
if t
is empty, else it is Some x
for some x
chosen uniformly at random from t
.
random_element
side-effects random_state
by calling Random.State.int
. If random_state
is not supplied, random_element
uses Random.State.default
.
val random_element_exn : ?random_state:Base.Random.State.t -> 'a list -> 'a
is_sorted t ~compare
returns true
iff for all adjacent a1; a2
in t
, compare
a1 a2 <= 0
.
is_sorted_strictly
is similar, except it uses <
instead of <=
.
module Infix : sig ... end
transpose m
transposes the rows and columns of the matrix m
, considered as either a row of column lists or (dually) a column of row lists.
Example:
transpose [[1;2;3];[4;5;6]] = [[1;4];[2;5];[3;6]]
On non-empty rectangular matrices, transpose
is an involution (i.e., transpose
(transpose m) = m
). Transpose returns None
when called on lists of lists with non-uniform lengths.
transpose_exn
transposes the rows and columns of its argument, throwing an exception if the list is not rectangular.
type 'a t = 'a Base.List.t
include Bin_prot.Binable.S1 with type 'a t := 'a t
val bin_shape_t : Bin_prot.Shape.t -> Bin_prot.Shape.t
val bin_size_t : ('a, 'a t) Bin_prot.Size.sizer1
val bin_write_t : ('a, 'a t) Bin_prot.Write.writer1
val bin_read_t : ('a, 'a t) Bin_prot.Read.reader1
val __bin_read_t__ : ('a, int -> 'a t) Bin_prot.Read.reader1
val bin_writer_t : ('a, 'a t) Bin_prot.Type_class.S1.writer
val bin_reader_t : ('a, 'a t) Bin_prot.Type_class.S1.reader
val bin_t : ('a, 'a t) Bin_prot.Type_class.S1.t
module Assoc : sig ... end
stable_dedup
Same as dedup
but maintains the order of the list and doesn't allow compare function to be specified (otherwise, the implementation in terms of Set.t would hide a heavyweight functor instantiation at each call).
val stable_dedup_staged : compare:('a -> 'a -> Base.Int.t) -> ('a Base.List.t -> 'a Base.List.t) Base.Staged.t
exception Duplicate_found of Base.Unit.t -> Base.Sexp.t * Base.String.t
Only raised in exn_if_dup
below.
val exn_if_dup : compare:('a -> 'a -> Base.Int.t) -> ?context:Base.String.t -> 'a t -> to_sexp:('a -> Base.Sexp.t) -> Base.Unit.t
exn_if_dup ~compare ?context t ~to_sexp
raises if t
contains a duplicate. It will specifically raise a Duplicate_found
exception and use context
as its second argument. O(n log n) time complexity.
val slice : 'a t -> Base.Int.t -> Base.Int.t -> 'a t
slice t start stop
returns a new list including elements t.(start)
through t.(stop-1)
, normalized Python-style with the exception that stop = 0
is treated as stop = length t
.
include Comparator.Derived with type 'a t := 'a t
val comparator : ('a, 'cmp) Comparator.comparator -> ('a t, 'cmp comparator_witness) Comparator.comparator
include Quickcheckable.S1 with type 'a t := 'a t
val quickcheck_generator : 'a Base_quickcheck.Generator.t -> 'a t Base_quickcheck.Generator.t
val quickcheck_observer : 'a Base_quickcheck.Observer.t -> 'a t Base_quickcheck.Observer.t
val quickcheck_shrinker : 'a Base_quickcheck.Shrinker.t -> 'a t Base_quickcheck.Shrinker.t
val to_string : f:('a -> Base.String.t) -> 'a t -> Base.String.t
val gen_non_empty : 'a Quickcheck.Generator.t -> 'a t Quickcheck.Generator.t
Like gen
, but never generates the empty list.
val gen_with_length : Base.Int.t -> 'a Quickcheck.Generator.t -> 'a t Quickcheck.Generator.t
Like gen
, but generates lists with the given length.
val gen_filtered : 'a t -> 'a t Quickcheck.Generator.t
Randomly drops elements from the input list. Length is chosen uniformly between 0 and the length of the input, inclusive.
val gen_permutations : 'a t -> 'a t Quickcheck.Generator.t
gen_permutations t
generates all permutations of list
. If t
contains duplicate values, then gen_permutations t
will produce duplicate lists.
val zip_with_remainder : 'a Base.List.t -> 'b Base.List.t -> ('a * 'b) Base.List.t * ('a Base.List.t, 'b Base.List.t) Either.t Base.Option.t
zip_with_remainder xs ys
zips as many elements as possible of xs
and ys
together and also returns the un-zipped remainder of the longer input, if the inputs have different lengths.
If xs
and ys
have the same length, zip_with_remainder xs ys
returns the same thing as (zip_exn xs ys, None)
module Stable : sig ... end