mirror of
https://github.com/c-cube/moonpool.git
synced 2025-12-17 08:06:43 -05:00
2 lines
No EOL
66 KiB
HTML
2 lines
No EOL
66 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Seq (ocaml.Stdlib.Seq)</title><link rel="stylesheet" href="../../../_odoc-theme/odoc.css"/><meta charset="utf-8"/><meta name="generator" content="odoc 2.2.1"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><script src="../../../highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body class="odoc"><nav class="odoc-nav"><a href="../index.html">Up</a> – <a href="../../index.html">ocaml</a> » <a href="../index.html">Stdlib</a> » Seq</nav><header class="odoc-preamble"><h1>Module <code><span>Stdlib.Seq</span></code></h1><p>Sequences.</p><p>A sequence of type <code>'a Seq.t</code> can be thought of as a <b>delayed list</b>, that is, a list whose elements are computed only when they are demanded by a consumer. This allows sequences to be produced and transformed lazily (one element at a time) rather than eagerly (all elements at once). This also allows constructing conceptually infinite sequences.</p><p>The type <code>'a Seq.t</code> is defined as a synonym for <code>unit -> 'a Seq.node</code>. This is a function type: therefore, it is opaque. The consumer can <b>query</b> a sequence in order to request the next element (if there is one), but cannot otherwise inspect the sequence in any way.</p><p>Because it is opaque, the type <code>'a Seq.t</code> does <i>not</i> reveal whether a sequence is:</p><ul><li><b>persistent</b>, which means that the sequence can be used as many times as desired, producing the same elements every time, just like an immutable list; or</li><li><b>ephemeral</b>, which means that the sequence is not persistent. Querying an ephemeral sequence might have an observable side effect, such as incrementing a mutable counter. As a common special case, an ephemeral sequence can be <b>affine</b>, which means that it must be queried at most once.</li></ul><p>It also does <i>not</i> reveal whether the elements of the sequence are:</p><ul><li><b>pre-computed and stored</b> in memory, which means that querying the sequence is cheap;</li><li><b>computed when first demanded and then stored</b> in memory, which means that querying the sequence once can be expensive, but querying the same sequence again is cheap; or</li><li><b>re-computed every time they are demanded</b>, which may or may not be cheap.</li></ul><p>It is up to the programmer to keep these distinctions in mind so as to understand the time and space requirements of sequences.</p><p>For the sake of simplicity, most of the documentation that follows is written under the implicit assumption that the sequences at hand are persistent. We normally do not point out <i>when</i> or <i>how many times</i> each function is invoked, because that would be too verbose. For instance, in the description of <code>map</code>, we write: "if <code>xs</code> is the sequence <code>x0; x1; ...</code> then <code>map f xs</code> is the sequence <code>f x0; f x1; ...</code>". If we wished to be more explicit, we could point out that the transformation takes place on demand: that is, the elements of <code>map f xs</code> are computed only when they are demanded. In other words, the definition <code>let ys = map f xs</code> terminates immediately and does not invoke <code>f</code>. The function call <code>f x0</code> takes place only when the first element of <code>ys</code> is demanded, via the function call <code>ys()</code>. Furthermore, calling <code>ys()</code> twice causes <code>f x0</code> to be called twice as well. If one wishes for <code>f</code> to be applied at most once to each element of <code>xs</code>, even in scenarios where <code>ys</code> is queried more than once, then one should use <code>let ys = memoize (map f xs)</code>.</p><p>As a general rule, the functions that build sequences, such as <code>map</code>, <code>filter</code>, <code>scan</code>, <code>take</code>, etc., produce sequences whose elements are computed only on demand. The functions that eagerly consume sequences, such as <code>is_empty</code>, <code>find</code>, <code>length</code>, <code>iter</code>, <code>fold_left</code>, etc., are the functions that force computation to take place.</p><p>When possible, we recommend using sequences rather than dispensers (functions of type <code>unit -> 'a option</code> that produce elements upon demand). Whereas sequences can be persistent or ephemeral, dispensers are always ephemeral, and are typically more difficult to work with than sequences. Two conversion functions, <a href="#val-to_dispenser"><code>to_dispenser</code></a> and <a href="#val-of_dispenser"><code>of_dispenser</code></a>, are provided.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.07</li></ul></header><nav class="odoc-toc"><ul><li><a href="#consuming-sequences">Consuming sequences</a></li><li><a href="#constructing-sequences">Constructing sequences</a></li><li><a href="#transforming-sequences">Transforming sequences</a></li><li><a href="#combining-sequences">Combining sequences</a></li><li><a href="#splitting-a-sequence-into-two-sequences">Splitting a sequence into two sequences</a></li><li><a href="#converting-between-sequences-and-dispensers">Converting between sequences and dispensers</a></li><li><a href="#sequences-of-integers">Sequences of integers</a></li></ul></nav><div class="odoc-content"><div class="odoc-spec"><div class="spec type anchored" id="type-t"><a href="#type-t" class="anchor"></a><code><span><span class="keyword">type</span> <span>'a t</span></span><span> = <span>unit <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-node">node</a></span></span></code></div><div class="spec-doc"><p>A sequence <code>xs</code> of type <code>'a t</code> is a delayed list of elements of type <code>'a</code>. Such a sequence is queried by performing a function application <code>xs()</code>. This function application returns a node, allowing the caller to determine whether the sequence is empty or nonempty, and in the latter case, to obtain its head and tail.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-node"><a href="#type-node" class="anchor"></a><code><span><span class="keyword">and</span> <span>+'a node</span></span><span> = </span></code><ol><li id="type-node.Nil" class="def variant constructor anchored"><a href="#type-node.Nil" class="anchor"></a><code><span>| </span><span><span class="constructor">Nil</span></span></code></li><li id="type-node.Cons" class="def variant constructor anchored"><a href="#type-node.Cons" class="anchor"></a><code><span>| </span><span><span class="constructor">Cons</span> <span class="keyword">of</span> <span class="type-var">'a</span> * <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></li></ol></div><div class="spec-doc"><p>A node is either <code>Nil</code>, which means that the sequence is empty, or <code>Cons (x, xs)</code>, which means that <code>x</code> is the first element of the sequence and that <code>xs</code> is the remainder of the sequence.</p></div></div><h2 id="consuming-sequences"><a href="#consuming-sequences" class="anchor"></a>Consuming sequences</h2><p>The functions in this section consume their argument, a sequence, either partially or completely:</p><ul><li><code>is_empty</code> and <code>uncons</code> consume the sequence down to depth 1. That is, they demand the first argument of the sequence, if there is one.</li><li><code>iter</code>, <code>fold_left</code>, <code>length</code>, etc., consume the sequence all the way to its end. They terminate only if the sequence is finite.</li><li><code>for_all</code>, <code>exists</code>, <code>find</code>, etc. consume the sequence down to a certain depth, which is a priori unpredictable.</li></ul><p>Similarly, among the functions that consume two sequences, one can distinguish two groups:</p><ul><li><code>iter2</code> and <code>fold_left2</code> consume both sequences all the way to the end, provided the sequences have the same length.</li><li><code>for_all2</code>, <code>exists2</code>, <code>equal</code>, <code>compare</code> consume the sequences down to a certain depth, which is a priori unpredictable.</li></ul><p>The functions that consume two sequences can be applied to two sequences of distinct lengths: in that case, the excess elements in the longer sequence are ignored. (It may be the case that one excess element is demanded, even though this element is not used.)</p><p>None of the functions in this section is lazy. These functions are consumers: they force some computation to take place.</p><div class="odoc-spec"><div class="spec value anchored" id="val-is_empty"><a href="#val-is_empty" class="anchor"></a><code><span><span class="keyword">val</span> is_empty : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p><code>is_empty xs</code> determines whether the sequence <code>xs</code> is empty.</p><p>It is recommended that the sequence <code>xs</code> be persistent. Indeed, <code>is_empty xs</code> demands the head of the sequence <code>xs</code>, so, if <code>xs</code> is ephemeral, it may be the case that <code>xs</code> cannot be used any more after this call has taken place.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-uncons"><a href="#val-uncons" class="anchor"></a><code><span><span class="keyword">val</span> uncons : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span> * <span><span class="type-var">'a</span> <a href="#type-t">t</a></span>)</span> option</span></span></code></div><div class="spec-doc"><p>If <code>xs</code> is empty, then <code>uncons xs</code> is <code>None</code>.</p><p>If <code>xs</code> is nonempty, then <code>uncons xs</code> is <code>Some (x, ys)</code> where <code>x</code> is the head of the sequence and <code>ys</code> its tail.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-length"><a href="#val-length" class="anchor"></a><code><span><span class="keyword">val</span> length : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> int</span></code></div><div class="spec-doc"><p><code>length xs</code> is the length of the sequence <code>xs</code>.</p><p>The sequence <code>xs</code> must be finite.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-iter"><a href="#val-iter" class="anchor"></a><code><span><span class="keyword">val</span> iter : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p><code>iter f xs</code> invokes <code>f x</code> successively for every element <code>x</code> of the sequence <code>xs</code>, from left to right.</p><p>It terminates only if the sequence <code>xs</code> is finite.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-fold_left"><a href="#val-fold_left" class="anchor"></a><code><span><span class="keyword">val</span> fold_left : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span class="type-var">'a</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span class="type-var">'a</span></span></code></div><div class="spec-doc"><p><code>fold_left f _ xs</code> invokes <code>f _ x</code> successively for every element <code>x</code> of the sequence <code>xs</code>, from left to right.</p><p>An accumulator of type <code>'a</code> is threaded through the calls to <code>f</code>.</p><p>It terminates only if the sequence <code>xs</code> is finite.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-iteri"><a href="#val-iteri" class="anchor"></a><code><span><span class="keyword">val</span> iteri : <span><span>(<span>int <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p><code>iteri f xs</code> invokes <code>f i x</code> successively for every element <code>x</code> located at index <code>i</code> in the sequence <code>xs</code>.</p><p>It terminates only if the sequence <code>xs</code> is finite.</p><p><code>iteri f xs</code> is equivalent to <code>iter (fun (i, x) -> f i x) (zip (ints 0) xs)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-fold_lefti"><a href="#val-fold_lefti" class="anchor"></a><code><span><span class="keyword">val</span> fold_lefti : <span><span>(<span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'b</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span class="type-var">'b</span></span></code></div><div class="spec-doc"><p><code>fold_lefti f _ xs</code> invokes <code>f _ i x</code> successively for every element <code>x</code> located at index <code>i</code> of the sequence <code>xs</code>.</p><p>An accumulator of type <code>'b</code> is threaded through the calls to <code>f</code>.</p><p>It terminates only if the sequence <code>xs</code> is finite.</p><p><code>fold_lefti f accu xs</code> is equivalent to <code>fold_left (fun accu (i, x) -> f accu i x) accu (zip (ints 0) xs)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-for_all"><a href="#val-for_all" class="anchor"></a><code><span><span class="keyword">val</span> for_all : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p><code>for_all p xs</code> determines whether all elements <code>x</code> of the sequence <code>xs</code> satisfy <code>p x</code>.</p><p>The sequence <code>xs</code> must be finite.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-exists"><a href="#val-exists" class="anchor"></a><code><span><span class="keyword">val</span> exists : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p><code>exists xs p</code> determines whether at least one element <code>x</code> of the sequence <code>xs</code> satisfies <code>p x</code>.</p><p>The sequence <code>xs</code> must be finite.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-find"><a href="#val-find" class="anchor"></a><code><span><span class="keyword">val</span> find : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> option</span></span></code></div><div class="spec-doc"><p><code>find p xs</code> returns <code>Some x</code>, where <code>x</code> is the first element of the sequence <code>xs</code> that satisfies <code>p x</code>, if there is such an element.</p><p>It returns <code>None</code> if there is no such element.</p><p>The sequence <code>xs</code> must be finite.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-find_map"><a href="#val-find_map" class="anchor"></a><code><span><span class="keyword">val</span> find_map : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> option</span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> option</span></span></code></div><div class="spec-doc"><p><code>find_map f xs</code> returns <code>Some y</code>, where <code>x</code> is the first element of the sequence <code>xs</code> such that <code>f x = Some _</code>, if there is such an element, and where <code>y</code> is defined by <code>f x = Some y</code>.</p><p>It returns <code>None</code> if there is no such element.</p><p>The sequence <code>xs</code> must be finite.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-iter2"><a href="#val-iter2" class="anchor"></a><code><span><span class="keyword">val</span> iter2 : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p><code>iter2 f xs ys</code> invokes <code>f x y</code> successively for every pair <code>(x, y)</code> of elements drawn synchronously from the sequences <code>xs</code> and <code>ys</code>.</p><p>If the sequences <code>xs</code> and <code>ys</code> have different lengths, then iteration stops as soon as one sequence is exhausted; the excess elements in the other sequence are ignored.</p><p>Iteration terminates only if at least one of the sequences <code>xs</code> and <code>ys</code> is finite.</p><p><code>iter2 f xs ys</code> is equivalent to <code>iter (fun (x, y) -> f x y) (zip xs ys)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-fold_left2"><a href="#val-fold_left2" class="anchor"></a><code><span><span class="keyword">val</span> fold_left2 : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span><span class="type-var">'c</span> <span class="arrow">-></span></span> <span class="type-var">'a</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'c</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span class="type-var">'a</span></span></code></div><div class="spec-doc"><p><code>fold_left2 f _ xs ys</code> invokes <code>f _ x y</code> successively for every pair <code>(x, y)</code> of elements drawn synchronously from the sequences <code>xs</code> and <code>ys</code>.</p><p>An accumulator of type <code>'a</code> is threaded through the calls to <code>f</code>.</p><p>If the sequences <code>xs</code> and <code>ys</code> have different lengths, then iteration stops as soon as one sequence is exhausted; the excess elements in the other sequence are ignored.</p><p>Iteration terminates only if at least one of the sequences <code>xs</code> and <code>ys</code> is finite.</p><p><code>fold_left2 f accu xs ys</code> is equivalent to <code>fold_left (fun accu (x, y) -> f accu x y) (zip xs ys)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-for_all2"><a href="#val-for_all2" class="anchor"></a><code><span><span class="keyword">val</span> for_all2 : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p><code>for_all2 p xs ys</code> determines whether all pairs <code>(x, y)</code> of elements drawn synchronously from the sequences <code>xs</code> and <code>ys</code> satisfy <code>p x y</code>.</p><p>If the sequences <code>xs</code> and <code>ys</code> have different lengths, then iteration stops as soon as one sequence is exhausted; the excess elements in the other sequence are ignored. In particular, if <code>xs</code> or <code>ys</code> is empty, then <code>for_all2 p xs ys</code> is true. This is where <code>for_all2</code> and <code>equal</code> differ: <code>equal eq xs ys</code> can be true only if <code>xs</code> and <code>ys</code> have the same length.</p><p>At least one of the sequences <code>xs</code> and <code>ys</code> must be finite.</p><p><code>for_all2 p xs ys</code> is equivalent to <code>for_all (fun b -> b) (map2 p xs ys)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-exists2"><a href="#val-exists2" class="anchor"></a><code><span><span class="keyword">val</span> exists2 : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p><code>exists2 p xs ys</code> determines whether some pair <code>(x, y)</code> of elements drawn synchronously from the sequences <code>xs</code> and <code>ys</code> satisfies <code>p x y</code>.</p><p>If the sequences <code>xs</code> and <code>ys</code> have different lengths, then iteration must stop as soon as one sequence is exhausted; the excess elements in the other sequence are ignored.</p><p>At least one of the sequences <code>xs</code> and <code>ys</code> must be finite.</p><p><code>exists2 p xs ys</code> is equivalent to <code>exists (fun b -> b) (map2 p xs ys)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-equal"><a href="#val-equal" class="anchor"></a><code><span><span class="keyword">val</span> equal : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p>Provided the function <code>eq</code> defines an equality on elements, <code>equal eq xs ys</code> determines whether the sequences <code>xs</code> and <code>ys</code> are pointwise equal.</p><p>At least one of the sequences <code>xs</code> and <code>ys</code> must be finite.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-compare"><a href="#val-compare" class="anchor"></a><code><span><span class="keyword">val</span> compare : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> int)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> int</span></code></div><div class="spec-doc"><p>Provided the function <code>cmp</code> defines a preorder on elements, <code>compare cmp xs ys</code> compares the sequences <code>xs</code> and <code>ys</code> according to the lexicographic preorder.</p><p>For more details on comparison functions, see <a href="../Array/index.html#val-sort"><code>Array.sort</code></a>.</p><p>At least one of the sequences <code>xs</code> and <code>ys</code> must be finite.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><h2 id="constructing-sequences"><a href="#constructing-sequences" class="anchor"></a>Constructing sequences</h2><p>The functions in this section are lazy: that is, they return sequences whose elements are computed only when demanded.</p><div class="odoc-spec"><div class="spec value anchored" id="val-empty"><a href="#val-empty" class="anchor"></a><code><span><span class="keyword">val</span> empty : <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>empty</code> is the empty sequence. It has no elements. Its length is 0.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-return"><a href="#val-return" class="anchor"></a><code><span><span class="keyword">val</span> return : <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>return x</code> is the sequence whose sole element is <code>x</code>. Its length is 1.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-cons"><a href="#val-cons" class="anchor"></a><code><span><span class="keyword">val</span> cons : <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>cons x xs</code> is the sequence that begins with the element <code>x</code>, followed with the sequence <code>xs</code>.</p><p>Writing <code>cons (f()) xs</code> causes the function call <code>f()</code> to take place immediately. For this call to be delayed until the sequence is queried, one must instead write <code>(fun () -> Cons(f(), xs))</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.11</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-init"><a href="#val-init" class="anchor"></a><code><span><span class="keyword">val</span> init : <span>int <span class="arrow">-></span></span> <span><span>(<span>int <span class="arrow">-></span></span> <span class="type-var">'a</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>init n f</code> is the sequence <code>f 0; f 1; ...; f (n-1)</code>.</p><p><code>n</code> must be nonnegative.</p><p>If desired, the infinite sequence <code>f 0; f 1; ...</code> can be defined as <code>map f (ints 0)</code>.</p><ul class="at-tags"><li class="raises"><span class="at-tag">raises</span> <span class="value">Invalid_argument</span> <p>if <code>n</code> is negative.</p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-unfold"><a href="#val-unfold" class="anchor"></a><code><span><span class="keyword">val</span> unfold : <span><span>(<span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span> * <span class="type-var">'b</span>)</span> option</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>unfold</code> constructs a sequence out of a step function and an initial state.</p><p>If <code>f u</code> is <code>None</code> then <code>unfold f u</code> is the empty sequence. If <code>f u</code> is <code>Some (x, u')</code> then <code>unfold f u</code> is the nonempty sequence <code>cons x (unfold f u')</code>.</p><p>For example, <code>unfold (function [] -> None | h :: t -> Some (h, t)) l</code> is equivalent to <code>List.to_seq l</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.11</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-repeat"><a href="#val-repeat" class="anchor"></a><code><span><span class="keyword">val</span> repeat : <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>repeat x</code> is the infinite sequence where the element <code>x</code> is repeated indefinitely.</p><p><code>repeat x</code> is equivalent to <code>cycle (return x)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-forever"><a href="#val-forever" class="anchor"></a><code><span><span class="keyword">val</span> forever : <span><span>(<span>unit <span class="arrow">-></span></span> <span class="type-var">'a</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>forever f</code> is an infinite sequence where every element is produced (on demand) by the function call <code>f()</code>.</p><p>For instance, <code>forever Random.bool</code> is an infinite sequence of random bits.</p><p><code>forever f</code> is equivalent to <code>map f (repeat ())</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-cycle"><a href="#val-cycle" class="anchor"></a><code><span><span class="keyword">val</span> cycle : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>cycle xs</code> is the infinite sequence that consists of an infinite number of repetitions of the sequence <code>xs</code>.</p><p>If <code>xs</code> is an empty sequence, then <code>cycle xs</code> is empty as well.</p><p>Consuming (a prefix of) the sequence <code>cycle xs</code> once can cause the sequence <code>xs</code> to be consumed more than once. Therefore, <code>xs</code> must be persistent.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-iterate"><a href="#val-iterate" class="anchor"></a><code><span><span class="keyword">val</span> iterate : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'a</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>iterate f x</code> is the infinite sequence whose elements are <code>x</code>, <code>f x</code>, <code>f (f x)</code>, and so on.</p><p>In other words, it is the orbit of the function <code>f</code>, starting at <code>x</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><h2 id="transforming-sequences"><a href="#transforming-sequences" class="anchor"></a>Transforming sequences</h2><p>The functions in this section are lazy: that is, they return sequences whose elements are computed only when demanded.</p><div class="odoc-spec"><div class="spec value anchored" id="val-map"><a href="#val-map" class="anchor"></a><code><span><span class="keyword">val</span> map : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'b</span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>map f xs</code> is the image of the sequence <code>xs</code> through the transformation <code>f</code>.</p><p>If <code>xs</code> is the sequence <code>x0; x1; ...</code> then <code>map f xs</code> is the sequence <code>f x0; f x1; ...</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-mapi"><a href="#val-mapi" class="anchor"></a><code><span><span class="keyword">val</span> mapi : <span><span>(<span>int <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'b</span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>mapi</code> is analogous to <code>map</code>, but applies the function <code>f</code> to an index and an element.</p><p><code>mapi f xs</code> is equivalent to <code>map2 f (ints 0) xs</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-filter"><a href="#val-filter" class="anchor"></a><code><span><span class="keyword">val</span> filter : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>filter p xs</code> is the sequence of the elements <code>x</code> of <code>xs</code> that satisfy <code>p x</code>.</p><p>In other words, <code>filter p xs</code> is the sequence <code>xs</code>, deprived of the elements <code>x</code> such that <code>p x</code> is false.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-filter_map"><a href="#val-filter_map" class="anchor"></a><code><span><span class="keyword">val</span> filter_map : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> option</span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>filter_map f xs</code> is the sequence of the elements <code>y</code> such that <code>f x = Some y</code>, where <code>x</code> ranges over <code>xs</code>.</p><p><code>filter_map f xs</code> is equivalent to <code>map Option.get (filter Option.is_some (map f xs))</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-scan"><a href="#val-scan" class="anchor"></a><code><span><span class="keyword">val</span> scan : <span><span>(<span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'b</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>If <code>xs</code> is a sequence <code>[x0; x1; x2; ...]</code>, then <code>scan f a0 xs</code> is a sequence of accumulators <code>[a0; a1; a2; ...]</code> where <code>a1</code> is <code>f a0 x0</code>, <code>a2</code> is <code>f a1 x1</code>, and so on.</p><p>Thus, <code>scan f a0 xs</code> is conceptually related to <code>fold_left f a0 xs</code>. However, instead of performing an eager iteration and immediately returning the final accumulator, it returns a sequence of accumulators.</p><p>For instance, <code>scan (+) 0</code> transforms a sequence of integers into the sequence of its partial sums.</p><p>If <code>xs</code> has length <code>n</code> then <code>scan f a0 xs</code> has length <code>n+1</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-take"><a href="#val-take" class="anchor"></a><code><span><span class="keyword">val</span> take : <span>int <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>take n xs</code> is the sequence of the first <code>n</code> elements of <code>xs</code>.</p><p>If <code>xs</code> has fewer than <code>n</code> elements, then <code>take n xs</code> is equivalent to <code>xs</code>.</p><p><code>n</code> must be nonnegative.</p><ul class="at-tags"><li class="raises"><span class="at-tag">raises</span> <span class="value">Invalid_argument</span> <p>if <code>n</code> is negative.</p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-drop"><a href="#val-drop" class="anchor"></a><code><span><span class="keyword">val</span> drop : <span>int <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>drop n xs</code> is the sequence <code>xs</code>, deprived of its first <code>n</code> elements.</p><p>If <code>xs</code> has fewer than <code>n</code> elements, then <code>drop n xs</code> is empty.</p><p><code>n</code> must be nonnegative.</p><p><code>drop</code> is lazy: the first <code>n+1</code> elements of the sequence <code>xs</code> are demanded only when the first element of <code>drop n xs</code> is demanded. For this reason, <code>drop 1 xs</code> is <i>not</i> equivalent to <code>tail xs</code>, which queries <code>xs</code> immediately.</p><ul class="at-tags"><li class="raises"><span class="at-tag">raises</span> <span class="value">Invalid_argument</span> <p>if <code>n</code> is negative.</p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-take_while"><a href="#val-take_while" class="anchor"></a><code><span><span class="keyword">val</span> take_while : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>take_while p xs</code> is the longest prefix of the sequence <code>xs</code> where every element <code>x</code> satisfies <code>p x</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-drop_while"><a href="#val-drop_while" class="anchor"></a><code><span><span class="keyword">val</span> drop_while : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>drop_while p xs</code> is the sequence <code>xs</code>, deprived of the prefix <code>take_while p xs</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-group"><a href="#val-group" class="anchor"></a><code><span><span class="keyword">val</span> group : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Provided the function <code>eq</code> defines an equality on elements, <code>group eq xs</code> is the sequence of the maximal runs of adjacent duplicate elements of the sequence <code>xs</code>.</p><p>Every element of <code>group eq xs</code> is a nonempty sequence of equal elements.</p><p>The concatenation <code>concat (group eq xs)</code> is equal to <code>xs</code>.</p><p>Consuming <code>group eq xs</code>, and consuming the sequences that it contains, can cause <code>xs</code> to be consumed more than once. Therefore, <code>xs</code> must be persistent.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-memoize"><a href="#val-memoize" class="anchor"></a><code><span><span class="keyword">val</span> memoize : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>The sequence <code>memoize xs</code> has the same elements as the sequence <code>xs</code>.</p><p>Regardless of whether <code>xs</code> is ephemeral or persistent, <code>memoize xs</code> is persistent: even if it is queried several times, <code>xs</code> is queried at most once.</p><p>The construction of the sequence <code>memoize xs</code> internally relies on suspensions provided by the module <a href="../Lazy/index.html"><code>Lazy</code></a>. These suspensions are <i>not</i> thread-safe. Therefore, the sequence <code>memoize xs</code> must <i>not</i> be queried by multiple threads concurrently.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec exception anchored" id="exception-Forced_twice"><a href="#exception-Forced_twice" class="anchor"></a><code><span><span class="keyword">exception</span> </span><span><span class="exception">Forced_twice</span></span></code></div><div class="spec-doc"><p>This exception is raised when a sequence returned by <a href="#val-once"><code>once</code></a> (or a suffix of it) is queried more than once.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-once"><a href="#val-once" class="anchor"></a><code><span><span class="keyword">val</span> once : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>The sequence <code>once xs</code> has the same elements as the sequence <code>xs</code>.</p><p>Regardless of whether <code>xs</code> is ephemeral or persistent, <code>once xs</code> is an ephemeral sequence: it can be queried at most once. If it (or a suffix of it) is queried more than once, then the exception <code>Forced_twice</code> is raised. This can be useful, while debugging or testing, to ensure that a sequence is consumed at most once.</p><ul class="at-tags"><li class="raises"><span class="at-tag">raises</span> <span class="value">Forced_twice</span> <p>if <code>once xs</code>, or a suffix of it, is queried more than once.</p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-transpose"><a href="#val-transpose" class="anchor"></a><code><span><span class="keyword">val</span> transpose : <span><span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>If <code>xss</code> is a matrix (a sequence of rows), then <code>transpose xss</code> is the sequence of the columns of the matrix <code>xss</code>.</p><p>The rows of the matrix <code>xss</code> are not required to have the same length.</p><p>The matrix <code>xss</code> is not required to be finite (in either direction).</p><p>The matrix <code>xss</code> must be persistent.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><h2 id="combining-sequences"><a href="#combining-sequences" class="anchor"></a>Combining sequences</h2><div class="odoc-spec"><div class="spec value anchored" id="val-append"><a href="#val-append" class="anchor"></a><code><span><span class="keyword">val</span> append : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>append xs ys</code> is the concatenation of the sequences <code>xs</code> and <code>ys</code>.</p><p>Its elements are the elements of <code>xs</code>, followed by the elements of <code>ys</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.11</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-concat"><a href="#val-concat" class="anchor"></a><code><span><span class="keyword">val</span> concat : <span><span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>If <code>xss</code> is a sequence of sequences, then <code>concat xss</code> is its concatenation.</p><p>If <code>xss</code> is the sequence <code>xs0; xs1; ...</code> then <code>concat xss</code> is the sequence <code>xs0 @ xs1 @ ...</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.13</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-flat_map"><a href="#val-flat_map" class="anchor"></a><code><span><span class="keyword">val</span> flat_map : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>flat_map f xs</code> is equivalent to <code>concat (map f xs)</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-concat_map"><a href="#val-concat_map" class="anchor"></a><code><span><span class="keyword">val</span> concat_map : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>concat_map f xs</code> is equivalent to <code>concat (map f xs)</code>.</p><p><code>concat_map</code> is an alias for <code>flat_map</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.13</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-zip"><a href="#val-zip" class="anchor"></a><code><span><span class="keyword">val</span> zip : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span> * <span class="type-var">'b</span>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>zip xs ys</code> is the sequence of pairs <code>(x, y)</code> drawn synchronously from the sequences <code>xs</code> and <code>ys</code>.</p><p>If the sequences <code>xs</code> and <code>ys</code> have different lengths, then the sequence ends as soon as one sequence is exhausted; the excess elements in the other sequence are ignored.</p><p><code>zip xs ys</code> is equivalent to <code>map2 (fun a b -> (a, b)) xs ys</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-map2"><a href="#val-map2" class="anchor"></a><code><span><span class="keyword">val</span> map2 : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span class="type-var">'c</span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'c</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>map2 f xs ys</code> is the sequence of the elements <code>f x y</code>, where the pairs <code>(x, y)</code> are drawn synchronously from the sequences <code>xs</code> and <code>ys</code>.</p><p>If the sequences <code>xs</code> and <code>ys</code> have different lengths, then the sequence ends as soon as one sequence is exhausted; the excess elements in the other sequence are ignored.</p><p><code>map2 f xs ys</code> is equivalent to <code>map (fun (x, y) -> f x y) (zip xs ys)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-interleave"><a href="#val-interleave" class="anchor"></a><code><span><span class="keyword">val</span> interleave : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>interleave xs ys</code> is the sequence that begins with the first element of <code>xs</code>, continues with the first element of <code>ys</code>, and so on.</p><p>When one of the sequences <code>xs</code> and <code>ys</code> is exhausted, <code>interleave xs ys</code> continues with the rest of the other sequence.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-sorted_merge"><a href="#val-sorted_merge" class="anchor"></a><code><span><span class="keyword">val</span> sorted_merge : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <span class="arrow">-></span></span> int)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>If the sequences <code>xs</code> and <code>ys</code> are sorted according to the total preorder <code>cmp</code>, then <code>sorted_merge cmp xs ys</code> is the sorted sequence obtained by merging the sequences <code>xs</code> and <code>ys</code>.</p><p>For more details on comparison functions, see <a href="../Array/index.html#val-sort"><code>Array.sort</code></a>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-product"><a href="#val-product" class="anchor"></a><code><span><span class="keyword">val</span> product : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span> * <span class="type-var">'b</span>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>product xs ys</code> is the Cartesian product of the sequences <code>xs</code> and <code>ys</code>.</p><p>For every element <code>x</code> of <code>xs</code> and for every element <code>y</code> of <code>ys</code>, the pair <code>(x, y)</code> appears once as an element of <code>product xs ys</code>.</p><p>The order in which the pairs appear is unspecified.</p><p>The sequences <code>xs</code> and <code>ys</code> are not required to be finite.</p><p>The sequences <code>xs</code> and <code>ys</code> must be persistent.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-map_product"><a href="#val-map_product" class="anchor"></a><code><span><span class="keyword">val</span> map_product : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span class="type-var">'c</span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'c</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>The sequence <code>map_product f xs ys</code> is the image through <code>f</code> of the Cartesian product of the sequences <code>xs</code> and <code>ys</code>.</p><p>For every element <code>x</code> of <code>xs</code> and for every element <code>y</code> of <code>ys</code>, the element <code>f x y</code> appears once as an element of <code>map_product f xs ys</code>.</p><p>The order in which these elements appear is unspecified.</p><p>The sequences <code>xs</code> and <code>ys</code> are not required to be finite.</p><p>The sequences <code>xs</code> and <code>ys</code> must be persistent.</p><p><code>map_product f xs ys</code> is equivalent to <code>map (fun (x, y) -> f x y) (product xs ys)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><h2 id="splitting-a-sequence-into-two-sequences"><a href="#splitting-a-sequence-into-two-sequences" class="anchor"></a>Splitting a sequence into two sequences</h2><div class="odoc-spec"><div class="spec value anchored" id="val-unzip"><a href="#val-unzip" class="anchor"></a><code><span><span class="keyword">val</span> unzip : <span><span><span>(<span class="type-var">'a</span> * <span class="type-var">'b</span>)</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span> * <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>unzip</code> transforms a sequence of pairs into a pair of sequences.</p><p><code>unzip xs</code> is equivalent to <code>(map fst xs, map snd xs)</code>.</p><p>Querying either of the sequences returned by <code>unzip xs</code> causes <code>xs</code> to be queried. Therefore, querying both of them causes <code>xs</code> to be queried twice. Thus, <code>xs</code> must be persistent and cheap. If that is not the case, use <code>unzip (memoize xs)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-split"><a href="#val-split" class="anchor"></a><code><span><span class="keyword">val</span> split : <span><span><span>(<span class="type-var">'a</span> * <span class="type-var">'b</span>)</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span> * <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>split</code> is an alias for <code>unzip</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-partition_map"><a href="#val-partition_map" class="anchor"></a><code><span><span class="keyword">val</span> partition_map : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'b</span>, <span class="type-var">'c</span>)</span> <a href="../Either/index.html#type-t">Either.t</a></span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span> * <span><span class="type-var">'c</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>partition_map f xs</code> returns a pair of sequences <code>(ys, zs)</code>, where:</p><ul><li><code>ys</code> is the sequence of the elements <code>y</code> such that <code>f x = Left y</code>, where <code>x</code> ranges over <code>xs</code>;</li></ul><ul><li><code>zs</code> is the sequence of the elements <code>z</code> such that <code>f x = Right z</code>, where <code>x</code> ranges over <code>xs</code>.</li></ul><p><code>partition_map f xs</code> is equivalent to a pair of <code>filter_map Either.find_left (map f xs)</code> and <code>filter_map Either.find_right (map f xs)</code>.</p><p>Querying either of the sequences returned by <code>partition_map f xs</code> causes <code>xs</code> to be queried. Therefore, querying both of them causes <code>xs</code> to be queried twice. Thus, <code>xs</code> must be persistent and cheap. If that is not the case, use <code>partition_map f (memoize xs)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-partition"><a href="#val-partition" class="anchor"></a><code><span><span class="keyword">val</span> partition : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span> * <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>partition p xs</code> returns a pair of the subsequence of the elements of <code>xs</code> that satisfy <code>p</code> and the subsequence of the elements of <code>xs</code> that do not satisfy <code>p</code>.</p><p><code>partition p xs</code> is equivalent to <code>filter p xs, filter (fun x -> not (p x)) xs</code>.</p><p>Consuming both of the sequences returned by <code>partition p xs</code> causes <code>xs</code> to be consumed twice and causes the function <code>f</code> to be applied twice to each element of the list. Therefore, <code>f</code> should be pure and cheap. Furthermore, <code>xs</code> should be persistent and cheap. If that is not the case, use <code>partition p (memoize xs)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><h2 id="converting-between-sequences-and-dispensers"><a href="#converting-between-sequences-and-dispensers" class="anchor"></a>Converting between sequences and dispensers</h2><p>A dispenser is a representation of a sequence as a function of type <code>unit -> 'a option</code>. Every time this function is invoked, it returns the next element of the sequence. When there are no more elements, it returns <code>None</code>. A dispenser has mutable internal state, therefore is ephemeral: the sequence that it represents can be consumed at most once.</p><div class="odoc-spec"><div class="spec value anchored" id="val-of_dispenser"><a href="#val-of_dispenser" class="anchor"></a><code><span><span class="keyword">val</span> of_dispenser : <span><span>(<span>unit <span class="arrow">-></span></span> <span><span class="type-var">'a</span> option</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>of_dispenser it</code> is the sequence of the elements produced by the dispenser <code>it</code>. It is an ephemeral sequence: it can be consumed at most once. If a persistent sequence is needed, use <code>memoize (of_dispenser it)</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-to_dispenser"><a href="#val-to_dispenser" class="anchor"></a><code><span><span class="keyword">val</span> to_dispenser : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>unit <span class="arrow">-></span></span> <span><span class="type-var">'a</span> option</span></span></code></div><div class="spec-doc"><p><code>to_dispenser xs</code> is a fresh dispenser on the sequence <code>xs</code>.</p><p>This dispenser has mutable internal state, which is not protected by a lock; so, it must not be used by several threads concurrently.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div><h2 id="sequences-of-integers"><a href="#sequences-of-integers" class="anchor"></a>Sequences of integers</h2><div class="odoc-spec"><div class="spec value anchored" id="val-ints"><a href="#val-ints" class="anchor"></a><code><span><span class="keyword">val</span> ints : <span>int <span class="arrow">-></span></span> <span>int <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>ints i</code> is the infinite sequence of the integers beginning at <code>i</code> and counting up.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.14</li></ul></div></div></div></body></html> |