Модуль Seq
module Seq: sig .. end
Последовательности.
Последовательность типа 'a Seq.t можно рассматривать как отложенный список, то есть список, элементы которого вычисляются только тогда, когда они нужны потребителю. Благодаря этому последовательности можно создавать и преобразовывать лениво (по одному элементу за раз), а не сразу (все элементы одновременно). Это также позволяет создавать концептуально бесконечные последовательности.
Тип 'a Seq.t определён как синоним unit -> 'a Seq.node. Это тип функции, а значит, он непрозрачен. Потребитель может запрашивать последовательность, чтобы получить следующий элемент (если он есть), но не может иначе исследовать её каким-либо образом.
Поскольку тип 'a Seq.t непрозрачен, он не позволяет определить, является ли последовательность:
- персистентной, то есть её можно использовать сколько угодно раз, каждый раз получая те же элементы, как и в случае неизменяемого списка; или
- эфемерной, то есть она не является персистентной. Запрос эфемерной последовательности может иметь наблюдаемый побочный эффект, например увеличивать изменяемый счётчик. В частном распространённом случае эфемерная последовательность может быть аффинной, то есть её можно запрашивать не более одного раза.
Он также не позволяет определить, являются ли элементы последовательности:
- предварительно вычисленными и сохранёнными в памяти, то есть запрос последовательности обходится дёшево;
- вычисляемыми при первом запросе и затем сохраняемыми в памяти, то есть первый запрос последовательности может быть затратным, но повторные запросы той же последовательности обходятся дёшево; или
- вычисляемыми заново при каждом запросе, что может быть как затратным, так и нет.
Программисту следует помнить об этих различиях, чтобы понимать требования последовательностей к времени и памяти.
Для простоты большая часть дальнейшей документации написана с неявным предположением, что рассматриваемые последовательности персистентны. Обычно мы не указываем, когда и сколько раз вызывается каждая функция, поскольку это сделало бы описание слишком многословным. Например, в описании map мы пишем: «если xs — последовательность x0; x1; ..., то map f xs — последовательность f x0; f x1; ...». Если бы мы хотели выразиться точнее, то могли бы отметить, что преобразование выполняется по запросу: элементы map f xs вычисляются только тогда, когда они нужны. Иными словами, определение let ys = map f xs завершается немедленно и не вызывает f. Вызов функции f x0 происходит только тогда, когда запрашивается первый элемент ys, посредством вызова функции ys(). Кроме того, два вызова ys() приводят и к двум вызовам f x0. Если требуется, чтобы f применялась к каждому элементу xs не более одного раза, даже если ys запрашивается несколько раз, следует использовать let ys = memoize (map f xs).
Как правило, функции, создающие последовательности, такие как map, filter, scan, take и т. д., создают последовательности, элементы которых вычисляются только по запросу. Функции, жадно потребляющие последовательности, такие как is_empty, find, length, iter, fold_left и т. д., принудительно запускают вычисления.
По возможности мы рекомендуем использовать последовательности, а не диспенсеры (функции типа unit -> 'a option, которые выдают элементы по запросу). Последовательности могут быть персистентными или эфемерными, тогда как диспенсеры всегда эфемерны и обычно сложнее в использовании, чем последовательности. Предусмотрены две функции преобразования: Seq.to_dispenser и Seq.of_dispenser.
- Начиная с версии 4.07
type 'a t = unit -> 'a node
Последовательность xs типа 'a t — это отложенный список элементов типа 'a. Запрос такой последовательности выполняется посредством применения функции xs(). Это применение функции возвращает узел, позволяя вызывающему коду определить, пуста последовательность или нет, а в последнем случае получить её голову и хвост.
type 'a node =
|
| Nil
|
|
| Cons of
|
Узел — это либо Nil, что означает, что последовательность пуста, либо Cons (x, xs), что означает, что x — первый элемент последовательности, а xs — её остаток.
Потребление последовательностей
Функции в этом разделе потребляют свой аргумент — последовательность — частично или полностью:
-
is_emptyиunconsпотребляют последовательность до глубины 1. То есть они запрашивают первый элемент последовательности, если он есть. -
iter,fold_left,lengthи т. д. потребляют последовательность до конца. Они завершаются только в том случае, если последовательность конечна. -
for_all,exists,findи т. д. потребляют последовательность до некоторой глубины, заранее непредсказуемой.
Аналогично среди функций, потребляющих две последовательности, можно выделить две группы:
-
iter2иfold_left2потребляют обе последовательности до конца, если их длины совпадают. -
for_all2,exists2,equal,compareпотребляют последовательности до некоторой глубины, заранее непредсказуемой.
Функции, потребляющие две последовательности, можно применять к последовательностям разной длины: в этом случае лишние элементы более длинной последовательности игнорируются. (Может быть запрошен один лишний элемент, хотя он и не используется.)
Ни одна из функций этого раздела не является ленивой. Это функции-потребители: они принудительно запускают вычисления.
val is_empty : 'a t -> bool
is_empty xs определяет, пуста ли последовательность xs.
Рекомендуется, чтобы последовательность xs была персистентной. Действительно, is_empty xs запрашивает голову последовательности xs, поэтому, если xs эфемерна, после этого вызова xs может стать непригодной для дальнейшего использования.
- Начиная с версии 4.14
val uncons : 'a t -> ('a * 'a t) option
Если xs пуста, то uncons xs — это None.
Если xs не пуста, то uncons xs — это Some (x, ys), где x — голова последовательности, а ys — её хвост.
- Начиная с версии 4.14
val length : 'a t -> int
length xs — длина последовательности xs.
Не завершается, если xs бесконечна.
- Начиная с версии 4.14
val iter : ('a -> unit) -> 'a t -> unit
iter f xs последовательно вызывает f x для каждого элемента x последовательности xs, слева направо.
Функция завершается только в том случае, если последовательность xs конечна.
val fold_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc
fold_left f _ xs последовательно вызывает f _ x для каждого элемента x последовательности xs, слева направо.
При вызовах f передаётся аккумулятор типа 'a.
Функция завершается только в том случае, если последовательность xs конечна.
val iteri : (int -> 'a -> unit) -> 'a t -> unit
iteri f xs последовательно вызывает f i x для каждого элемента x, находящегося по индексу i в последовательности xs.
Функция завершается только в том случае, если последовательность xs конечна.
iteri f xs эквивалентна iter (fun (i, x) -> f i x) (zip (ints 0) xs).
- Начиная с версии 4.14
val fold_lefti : ('acc -> int -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc
fold_lefti f _ xs последовательно вызывает f _ i x для каждого элемента x, находящегося по индексу i последовательности xs.
При вызовах f передаётся аккумулятор типа 'b.
Функция завершается только в том случае, если последовательность xs конечна.
fold_lefti f accu xs эквивалентна fold_left (fun accu (i, x) -> f accu i x) accu (zip (ints 0) xs).
- Начиная с версии 4.14
val for_all : ('a -> bool) -> 'a t -> bool
for_all p xs определяет, удовлетворяют ли все элементы x последовательности xs условию p x.
Может не завершиться, если xs бесконечна.
- Начиная с версии 4.14
val exists : ('a -> bool) -> 'a t -> bool
exists p xs определяет, удовлетворяет ли хотя бы один элемент x последовательности xs условию p x.
Может не завершиться, если xs бесконечна.
- Начиная с версии 4.14
val find : ('a -> bool) -> 'a t -> 'a option
find p xs возвращает Some x, где x — первый элемент последовательности xs, удовлетворяющий условию p x, если такой элемент существует.
Если такого элемента нет, возвращается None.
Может не завершиться, если xs бесконечна.
- Начиная с версии 4.14
val find_index : ('a -> bool) -> 'a t -> int option
find_index p xs возвращает Some i, где i — индекс первого элемента последовательности xs, удовлетворяющего условию p x, если такой элемент существует.
Если такого элемента нет, возвращается None.
Может не завершиться, если xs бесконечна.
- Начиная с версии 5.1
val find_map : ('a -> 'b option) -> 'a t -> 'b option
find_map f xs возвращает Some y, где x — первый элемент последовательности xs, для которого выполняется f x = Some _, если такой элемент существует, а y определяется с помощью f x = Some y.
Если такого элемента нет, возвращается None.
Может не завершиться, если xs бесконечна.
- Начиная с версии 4.14
val find_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b option
То же, что и find_map, но предикат применяется к индексу элемента (отсчёт начинается с 0) как к первому аргументу, а к самому элементу — как ко второму.
Может не завершиться, если xs бесконечна.
- Начиная с версии 5.1
val iter2 : ('a -> 'b -> unit) -> 'a t -> 'b t -> unit
iter2 f xs ys последовательно вызывает f x y для каждой пары (x, y) элементов, синхронно взятых из последовательностей xs и ys.
Если последовательности xs и ys имеют разную длину, итерация прекращается, как только одна из последовательностей исчерпана; лишние элементы другой последовательности игнорируются.
Итерация завершается только в том случае, если хотя бы одна из последовательностей xs и ys конечна.
iter2 f xs ys эквивалентна iter (fun (x, y) -> f x y) (zip xs ys).
- Начиная с версии 4.14
val fold_left2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc
fold_left2 f _ xs ys последовательно вызывает f _ x y для каждой пары (x, y) элементов, синхронно взятых из последовательностей xs и ys.
При вызовах f передаётся аккумулятор типа 'a.
Если последовательности xs и ys имеют разную длину, итерация прекращается, как только одна из последовательностей исчерпана; лишние элементы другой последовательности игнорируются.
Итерация завершается только в том случае, если хотя бы одна из последовательностей xs и ys конечна.
fold_left2 f accu xs ys эквивалентна fold_left (fun accu (x, y) -> f accu x y) (zip xs ys).
- Начиная с версии 4.14
val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
for_all2 p xs ys определяет, удовлетворяют ли условию p x y все пары (x, y) элементов, синхронно взятых из последовательностей xs и ys.
Если последовательности xs и ys имеют разную длину, итерация прекращается, как только одна из последовательностей исчерпана; лишние элементы другой последовательности игнорируются. В частности, если xs или ys пуста, то for_all2 p xs ys истинно. В этом состоит различие между for_all2 и equal: equal eq xs ys может быть истинным только в том случае, если xs и ys имеют одинаковую длину.
Может не завершиться, если обе последовательности xs и ys бесконечны.
for_all2 p xs ys эквивалентна for_all (fun b -> b) (map2 p xs ys).
- Начиная с версии 4.14
val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
exists2 p xs ys определяет, удовлетворяет ли условию p x y хотя бы одна пара (x, y) элементов, синхронно взятых из последовательностей xs и ys.
Если последовательности xs и ys имеют разную длину, итерацию необходимо прекратить, как только одна из последовательностей исчерпана; лишние элементы другой последовательности игнорируются.
Может не завершиться, если обе последовательности xs и ys бесконечны.
exists2 p xs ys эквивалентна exists (fun b -> b) (map2 p xs ys).
- Начиная с версии 4.14
val equal : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
Если функция eq задаёт отношение равенства на элементах, equal eq xs ys определяет, равны ли последовательности xs и ys в каждой точке.
Может не завершиться, если обе последовательности xs и ys бесконечны.
- Начиная с версии 4.14
val compare : ('a -> 'b -> int) -> 'a t -> 'b t -> int
Если функция cmp задаёт предпорядок на элементах, compare cmp xs ys сравнивает последовательности xs и ys согласно лексикографическому предпорядку.
Подробнее о функциях сравнения см. в описании Array.sort.
Может не завершиться, если обе последовательности xs и ys бесконечны.
- Начиная с версии 4.14
Создание последовательностей
Функции в этом разделе являются ленивыми: они возвращают последовательности, элементы которых вычисляются только по запросу.
val empty : 'a t
empty — пустая последовательность. В ней нет элементов. Её длина равна 0.
val return : 'a -> 'a t
return x — последовательность, единственный элемент которой — x. Её длина равна 1.
val cons : 'a -> 'a t -> 'a t
cons x xs — последовательность, начинающаяся с элемента x, за которым следует последовательность xs.
Запись cons (f()) xs приводит к немедленному вызову функции f(). Чтобы отложить этот вызов до запроса последовательности, следует вместо этого написать (fun () -> Cons(f(), xs)).
- Начиная с версии 4.11
val singleton : 'a -> 'a t
singleton x возвращает последовательность из одного элемента, содержащую только x.
- Начиная с версии 5.4
val init : int -> (int -> 'a) -> 'a t
init n f — это последовательность f 0; f 1; ...; f (n-1).
n должно быть неотрицательным.
При необходимости бесконечную последовательность f 0; f 1; ... можно определить как map f (ints 0).
- Начиная с версии 4.14
-
Вызывает исключение
Invalid_argument, еслиnотрицательно.
val unfold : ('b -> ('a * 'b) option) -> 'b -> 'a t
unfold создаёт последовательность на основе функции шага и начального состояния.
Если f u равно None, то unfold f u — пустая последовательность. Если f u равно Some (x, u'), то unfold f u — непустая последовательность cons x (unfold f u').
Например, unfold (function [] -> None | h :: t -> Some (h, t)) l эквивалентно List.to_seq l.
- Начиная с версии 4.11
val repeat : 'a -> 'a t
repeat x — бесконечная последовательность, в которой элемент x повторяется бесконечно.
repeat x эквивалентно cycle (return x).
- Начиная с версии 4.14
val forever : (unit -> 'a) -> 'a t
forever f — бесконечная последовательность, каждый элемент которой создаётся (по запросу) вызовом функции f().
Например, forever Random.bool — бесконечная последовательность случайных битов.
forever f эквивалентно map f (repeat ()).
- Начиная с версии 4.14
val cycle : 'a t -> 'a t
cycle xs — бесконечная последовательность, состоящая из бесконечного числа повторений последовательности xs.
Если xs — пустая последовательность, то cycle xs также пуста.
Однократное потребление (префикса) последовательности cycle xs может привести к многократному потреблению последовательности xs. Поэтому xs должна быть персистентной.
- Начиная с версии 4.14
val iterate : ('a -> 'a) -> 'a -> 'a t
iterate f x — бесконечная последовательность, элементы которой равны x, f x, f (f x) и так далее.
Иными словами, это орбита функции f, начинающаяся с x.
- Начиная с версии 4.14
val delay : (unit -> 'a t) -> 'a t
delay (fun () -> seq) содержит те же элементы, что и seq, но выражение seq вычисляется только при запросе первого элемента.
Например,
let rec of_tree t =
match t with
| Leaf v -> Seq.return v
| Node(l, r) -> Seq.append (of_tree l) (of_tree r)
работает не так, как ожидается, поскольку строго обходит входное дерево, даже если выходная последовательность не вычисляется.
Вместо этого эту функцию можно записать следующим образом:
let rec of_tree t =
Seq.delay @@ fun () ->
match t with
| Leaf v -> Seq.return v
| Node(l, r) -> Seq.append (of_tree l) (of_tree r)
- Начиная с версии 5.5
Преобразование последовательностей
Функции в этом разделе являются ленивыми: они возвращают последовательности, элементы которых вычисляются только по запросу.
val map : ('a -> 'b) -> 'a t -> 'b t
map f xs — это образ последовательности xs при преобразовании f.
Если xs — последовательность x0; x1; ..., то map f xs — последовательность f x0; f x1; ....
val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t
mapi аналогична map, но применяет функцию f к индексу и элементу.
mapi f xs эквивалентна map2 f (ints 0) xs.
- Начиная с версии 4.14
val filter : ('a -> bool) -> 'a t -> 'a t
filter p xs — последовательность элементов x из xs, удовлетворяющих условию p x.
Иными словами, filter p xs — это последовательность xs без элементов x, для которых p x ложно.
val filteri : (int -> 'a -> bool) -> 'a t -> 'a t
То же, что и Seq.filter, но предикат применяется к индексу элемента (отсчёт начинается с 0) как к первому аргументу, а к самому элементу — как ко второму.
- Начиная с версии 5.4
val filter_map : ('a -> 'b option) -> 'a t -> 'b t
filter_map f xs — последовательность элементов y, для которых выполняется f x = Some y, где x принимает значения из xs.
filter_map f xs эквивалентна map Option.get (filter Option.is_some (map f xs)).
val scan : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b t
Если xs — последовательность [x0; x1; x2; ...], то scan f a0 xs — последовательность аккумуляторов [a0; a1; a2; ...], где a1 равно f a0 x0, a2 равно f a1 x1 и так далее.
Таким образом, scan f a0 xs концептуально связана с fold_left f a0 xs. Однако вместо выполнения жадной итерации и немедленного возврата итогового аккумулятора эта функция возвращает последовательность аккумуляторов.
Например, scan (+) 0 преобразует последовательность целых чисел в последовательность её частичных сумм.
Если длина xs равна n, то длина scan f a0 xs равна n+1.
- Начиная с версии 4.14
val take : int -> 'a t -> 'a t
take n xs — последовательность из первых n элементов xs.
Если в xs меньше n элементов, то take n xs эквивалентна xs.
n должно быть неотрицательным.
- Начиная с версии 4.14
-
Вызывает исключение
Invalid_argument, еслиnотрицательно.
val drop : int -> 'a t -> 'a t
drop n xs — это последовательность xs без первых n элементов.
Если в xs меньше n элементов, то drop n xs пуста.
n должно быть неотрицательным.
drop является ленивой: первые n+1 элементов последовательности xs запрашиваются только при запросе первого элемента drop n xs.
- Начиная с версии 4.14
-
Вызывает исключение
Invalid_argument, еслиnотрицательно.
val take_while : ('a -> bool) -> 'a t -> 'a t
take_while p xs — самый длинный префикс последовательности xs, в котором каждый элемент x удовлетворяет условию p x.
- Начиная с версии 4.14
val drop_while : ('a -> bool) -> 'a t -> 'a t
drop_while p xs — это последовательность xs без префикса take_while p xs.
- Начиная с версии 4.14
val group : ('a -> 'a -> bool) -> 'a t -> 'a t t
Если функция eq задаёт отношение равенства на элементах, group eq xs — последовательность максимальных групп соседних повторяющихся элементов последовательности xs.
Каждый элемент group eq xs — непустая последовательность одинаковых элементов.
Конкатенация concat (group eq xs) равна xs.
Потребление group eq xs и содержащихся в ней последовательностей может привести к многократному потреблению xs. Поэтому xs должна быть персистентной.
- Начиная с версии 4.14
val memoize : 'a t -> 'a t
Последовательность memoize xs содержит те же элементы, что и последовательность xs.
Независимо от того, является ли xs эфемерной или персистентной, memoize xs персистентна: даже если её запрашивают несколько раз, xs запрашивается не более одного раза.
Создание последовательности memoize xs внутри себя использует отложенные вычисления, предоставляемые модулем Lazy. Эти отложенные вычисления не являются потокобезопасными. Поэтому последовательность memoize xs нельзя одновременно запрашивать из нескольких потоков.
- Начиная с версии 4.14
exception Forced_twice
Это исключение возникает, если последовательность, возвращённая функцией Seq.once (или её суффикс), запрашивается более одного раза.
- Начиная с версии 4.14
val once : 'a t -> 'a t
Последовательность once xs содержит те же элементы, что и последовательность xs.
Независимо от того, является ли xs эфемерной или персистентной, once xs — эфемерная последовательность: её можно запросить не более одного раза. Если её (или её суффикс) запрашивают более одного раза, возникает исключение Forced_twice. Это может быть полезно при отладке или тестировании, чтобы убедиться, что последовательность потребляется не более одного раза.
- Начиная с версии 4.14
-
Вызывает исключение
Forced_twice, еслиonce xsили её суффикс запрашивается более одного раза.
val transpose : 'a t t -> 'a t t
Если xss — матрица (последовательность строк), то transpose xss — последовательность столбцов матрицы xss.
Строки матрицы xss не обязаны иметь одинаковую длину.
Матрица xss не обязана быть конечной (ни в одном из направлений).
Матрица xss должна быть персистентной.
- Начиная с версии 4.14
Объединение последовательностей
val append : 'a t -> 'a t -> 'a t
append xs ys — конкатенация последовательностей xs и ys.
Сначала идут элементы xs, за которыми следуют элементы ys.
- Начиная с версии 4.11
val concat : 'a t t -> 'a t
Если xss является последовательностью последовательностей, то concat xss — её конкатенация.
Если xss — последовательность xs0; xs1; ..., то concat xss — последовательность xs0 @ xs1 @ ....
- С версии 4.13
val flat_map : ('a -> 'b t) -> 'a t -> 'b t
flat_map f xs эквивалентно concat (map f xs).
val concat_map : ('a -> 'b t) -> 'a t -> 'b t
concat_map f xs эквивалентно concat (map f xs).
concat_map — это псевдоним для flat_map.
- С версии 4.13
val zip : 'a t -> 'b t -> ('a * 'b) t
zip xs ys — это последовательность пар (x, y), синхронно полученных из последовательностей xs и ys.
Если последовательности xs и ys имеют разную длину, последовательность заканчивается, как только исчерпывается одна из них; оставшиеся элементы другой последовательности игнорируются.
zip xs ys эквивалентно map2 (fun a b -> (a, b)) xs ys.
- С версии 4.14
val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
map2 f xs ys — это последовательность элементов f x y, где пары (x, y) синхронно получены из последовательностей xs и ys.
Если последовательности xs и ys имеют разную длину, последовательность заканчивается, как только исчерпывается одна из них; оставшиеся элементы другой последовательности игнорируются.
map2 f xs ys эквивалентно map (fun (x, y) -> f x y) (zip xs ys).
- С версии 4.14
val interleave : 'a t -> 'a t -> 'a t
interleave xs ys — это последовательность, которая начинается с первого элемента xs, продолжается первым элементом ys и так далее.
Когда одна из последовательностей xs и ys исчерпывается, interleave xs ys продолжается оставшейся частью другой последовательности.
- С версии 4.14
val sorted_merge : ('a -> 'a -> int) -> 'a t -> 'a t -> 'a t
Если последовательности xs и ys отсортированы в соответствии с полным предпорядком cmp, то sorted_merge cmp xs ys — это отсортированная последовательность, полученная слиянием последовательностей xs и ys.
Дополнительные сведения о функциях сравнения см. в разделе Array.sort.
- С версии 4.14
val product : 'a t -> 'b t -> ('a * 'b) t
product xs ys — это декартово произведение последовательностей xs и ys.
Для каждого элемента x из xs и каждого элемента y из ys пара (x, y) встречается ровно один раз как элемент product xs ys.
Порядок появления пар не определён.
Последовательности xs и ys не обязаны быть конечными.
Последовательности xs и ys должны быть персистентными.
- С версии 4.14
val map_product : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
Последовательность map_product f xs ys — это образ декартова произведения последовательностей xs и ys посредством f.
Для каждого элемента x из xs и каждого элемента y из ys элемент f x y встречается ровно один раз как элемент map_product f xs ys.
Порядок появления этих элементов не определён.
Последовательности xs и ys не обязаны быть конечными.
Последовательности xs и ys должны быть персистентными.
map_product f xs ys эквивалентно map (fun (x, y) -> f x y) (product xs ys).
- С версии 4.14
Разделение последовательности на две последовательности
val unzip : ('a * 'b) t -> 'a t * 'b t
unzip преобразует последовательность пар в пару последовательностей.
unzip xs эквивалентно (map fst xs, map snd xs).
Обращение к любой из последовательностей, возвращаемых unzip xs, приводит к обращению к xs. Поэтому обращение к обеим последовательностям приводит к двукратному обращению к xs. Следовательно, xs должна быть персистентной и дешёвой. Если это не так, используйте unzip (memoize xs).
- С версии 4.14
val split : ('a * 'b) t -> 'a t * 'b t
split — это псевдоним для unzip.
- С версии 4.14
val partition_map : ('a -> ('b, 'c) Either.t) -> 'a t -> 'b t * 'c t
partition_map f xs возвращает пару последовательностей (ys, zs), где:
-
ys— это последовательность элементовyтаких, чтоf x = Left y, гдеxпробегает значения изxs;
-
zs— это последовательность элементовzтаких, чтоf x = Right z, гдеxпробегает значения изxs.
partition_map f xs эквивалентно паре filter_map Either.find_left (map f xs) и filter_map Either.find_right (map f xs).
Обращение к любой из последовательностей, возвращаемых partition_map f xs, приводит к обращению к xs. Поэтому обращение к обеим последовательностям приводит к двукратному обращению к xs. Следовательно, xs должна быть персистентной и дешёвой. Если это не так, используйте partition_map f (memoize xs).
- С версии 4.14
val partition : ('a -> bool) -> 'a t -> 'a t * 'a t
partition p xs возвращает пару, состоящую из подпоследовательности элементов xs, удовлетворяющих условию p, и подпоследовательности элементов xs, не удовлетворяющих условию p.
partition p xs эквивалентно filter p xs, filter (fun x -> not (p x)) xs.
Обход обеих последовательностей, возвращаемых partition p xs, приводит к двукратному обходу xs и двукратному применению функции p к каждому элементу последовательности. Поэтому p должна быть чистой и дешёвой. Кроме того, xs должна быть персистентной и дешёвой. Если это не так, используйте partition p (memoize xs).
- С версии 4.14
Преобразование последовательностей в диспенсеры и обратно
Диспенсер — это представление последовательности в виде функции типа unit -> 'a option. При каждом вызове эта функция возвращает следующий элемент последовательности. Когда элементы заканчиваются, она возвращает None. У диспенсера есть изменяемое внутреннее состояние, поэтому он является эфемерным: представленную им последовательность можно обойти не более одного раза.
val of_dispenser : (unit -> 'a option) -> 'a t
of_dispenser it — это последовательность элементов, выдаваемых диспенсером it. Она является эфемерной: её можно обойти не более одного раза. Если нужна персистентная последовательность, используйте memoize (of_dispenser it).
- С версии 4.14
val to_dispenser : 'a t -> unit -> 'a option
to_dispenser xs — это новый диспенсер для последовательности xs.
У этого диспенсера есть изменяемое внутреннее состояние, не защищённое блокировкой; поэтому его нельзя одновременно использовать в нескольких потоках.
- С версии 4.14
Последовательности целых чисел
val ints : int -> int t
ints i — это бесконечная последовательность целых чисел, начинающаяся с i и возрастающая на единицу.
- С версии 4.14
© 1995-2026 INRIA.
https://ocaml.org/manual/5.5/api/Seq.html