Module SupplyDefault.Ephemeral
include S.Ephemeral
type 'a tA sequence
sof type'a tis a mutable data structure which represents a mathematical sequence of elements of type'a.
Construction
val create : 'a -> 'a tcreate defaultconstructs and returns a new empty sequence. The default valuedefaultis used to fill empty array slots.Time complexity: O(K).
val make : 'a -> Sek__.PublicSignature.length -> 'a -> 'a tmake default n vconstructs and returns a fresh sequence whose length isnand which consists ofncopies of the valuev. It is equivalent toof_array default (Array.make n v).Time complexity: O(n + K).
val init : 'a -> Sek__.PublicSignature.length -> (Sek__.PublicSignature.index -> 'a) -> 'a tinit default n fconstructs and returns a fresh sequence whose length isnand whose elements are the values produced by the callsf 0,f 1, ...f (n-1), in this order. It is equivalent toof_array default (Array.init n f).Time complexity: O(n + K), not counting the cost of the function
f.
Accessors
val default : 'a t -> 'adefault sreturns the value that is used to fill empty array slots in the sequences.Time complexity: O(1).
val length : 'a t -> Sek__.PublicSignature.lengthlength sreturns the length of the sequences.Time complexity: O(1).
val is_empty : 'a t -> boolis_empty sreturnstrueif the sequencesis empty andfalseotherwise. It is equivalent tolength s = 0.Time complexity: O(1).
Assignment and Copy
val clear : 'a t -> unitclear sempties the sequences.Time complexity: O(K), unless the global parameter
overwrite_empty_slotsisfalse, in which case the complexity is O(1).
val copy : ?mode:[ `Copy | `Share ] -> 'a t -> 'a tcopy ~mode sconstructs and returns a copys'of the sequences. The sequencessands'initially have the same elements, and can thereafter be modified independently of one another. Several copying modes are available, which have the same observable behavior, but offer distinct performance characteristics:copy ~mode:`Copy screates a sequence that is physically disjoint froms. All of the elements are copied one by one. It takes linear time, which is slow, but on the upside, it has no latent cost. The sequencesis unaffected, and the sequences'has unique ownership of its chunks.
copy ~mode:`Share screates a sequence whose chunks are physically shared with those ofs. The copying of individual chunks is delayed untilsors'is actually modified. This operation has complexity O(K), which is fast, but on the downside, there is a latent cost: subsequent update operations onsands'are more costly.
The default mode is
`Copy. That is,copy sis a short-hand forcopy ~mode:`Copy s.Time complexity: O(n + K) in
`Sharemode; O(K) in`Copymode.
val assign : 'a t -> 'a t -> unitIf
s1ands2are distinct sequences, thenassign s1 s2movess2's elements intos1, overwritings1's previous content, and clearss2. Ifs1ands2are the same sequence, thenassign s1 s2has no effect.Time complexity: O(1) in the special case where
s2is never used afterwards; otherwise O(K).
Stack Operations
val push : S.side -> 'a t -> 'a -> unitpush side s xpushes the elementxonto the front or back end of the sequences. The parametersidedetermines which end of the sequence is acted upon.Time complexity: O(log n) in the worst case. That said, in practice, most
pushoperations execute in O(1).
val pop : S.side -> 'a t -> 'aIf the sequence
sis nonempty, thenpop side spops an elementxoff the front or back end of the sequencesand returnsx. The parametersidedetermines which end of the sequence is acted upon. If the sequencesis empty, the exceptionS.Emptyis raised.Time complexity: same as
push.
val pop_opt : S.side -> 'a t -> 'a optionIf the sequence
sis nonempty, thenpop_opt side spops an elementxoff the front or back end of the sequencesand returnsSome x. The parametersidedetermines which end of the sequence is acted upon. If the sequencesis empty,Noneis returned.Time complexity: same as
pop.
val peek : S.side -> 'a t -> 'aIf the sequence
sis nonempty, thenpeek side sreads the elementxfound at the front or back end of the sequencesand returnsx. The parametersidedetermines which end of the sequence is acted upon. If the sequencesis empty, the exceptionS.Emptyis raised.Time complexity: O(1).
val peek_opt : S.side -> 'a t -> 'a optionIf the sequence
sis nonempty, thenpeek_opt side sreads the elementxfound at the front or back end of the sequencesand returnsSome x. The parametersidedetermines which end of the sequence is acted upon. If the sequencesis empty,Noneis returned.Time complexity: O(1).
Random Access
val get : 'a t -> Sek__.PublicSignature.index -> 'aget s ireturns the elementxlocated at indexiin the sequences. The indeximust lie in the semi-open interval[0, length s).Time complexity: O(log n), or, more precisely, O(log (min (i, n - i))).
val set : 'a t -> Sek__.PublicSignature.index -> 'a -> unitset s i xreplaces the element located at indexiin the sequenceswith the elementx. The indeximust lie in the semi-open interval[0, length s). The sequencesis updated in place.Time complexity: if the
setoperation hits a chunk that is marked as potentially shared with other sequences, then its complexity is O(K + log n), and this chunk is replaced in the process with one that is not shared with any other sequence. Otherwise, the complexity is O(log n), or, more precisely, O(log (min (i, n - i))).
Concatenation and Splitting
val concat : 'a t -> 'a t -> 'a tconcat s1 s2creates and returns a new sequence whose content is the concatenation of the sequencess1ands2. The sequencess1ands2are cleared. The sequencess1ands2must be distinct.concatis slightly less efficient thanappend, whose use should be preferred.Time complexity: in pathological cases,
concatcan cost as much as O(K + log^2 n), where n is the length of the result of the concatenation. In most cases, however, we expectconcatto cost O(K + log n). In the particular case of a concatenation that involves sequences whose chunks have never been shared, a more precise bound is O(K + log (min(n1, n2))), where n1 and n2 denote the lengths of the two sequences.
val append : S.side -> 'a t -> 'a t -> unitappend back s1 s2is equivalent toassign s1 (concat s1 s2). Thus,s1is assigned the concatenation of the sequencess1ands2, whiles2is cleared. In other words,append back s1 s2appends the sequences2at the back end of the sequences1.append front s1 s2is equivalent toassign s1 (concat s2 s1). Thus,s1is assigned the concatenation of the sequencess2ands1, whiles2is cleared. In other words,append front s1 s2prepends the sequences2at the front end of the sequences1.In either case, the sequences
s1ands2must be distinct.Time complexity: same as
concat.
val split : 'a t -> Sek__.PublicSignature.index -> 'a t * 'a tsplit s isplits the sequencesat indexi. It returns two new sequencess1ands2such that the length ofs1isiand the concatenation ofs1ands2iss. The sequencesis cleared. The indeximust lie in the closed interval[0, length s].splitis slightly less efficient thancarve, whose use should be preferred.Time complexity: in pathological cases,
splitcan cost as much as O(K + log^2 n), where n is the length of the result of the concatenation. In most cases, however, we expectsplitto cost O(K + log n), or, more precisely, O(K + log (min (i, n - i))). The latter bound holds, in particular, when the operation involves a sequence whose chunks have never been shared.
val carve : S.side -> 'a t -> Sek__.PublicSignature.index -> 'a tcarve back s iis equivalent tolet s1, s2 = split s i in assign s s1; s2. Thus, it splits the sequencesat indexiinto two parts: the first part is written tos, while the second part is returned.carve front s iis equivalent tolet s1, s2 = split s i in assign s s2; s1. Thus, it splits the sequencesat indexiinto two parts: the second part is written tos, while the first part is returned.In either case, the index
imust lie in the closed interval[0, length s].Time complexity: same as
split.
val take : S.side -> 'a t -> Sek__.PublicSignature.index -> unittake side s iis equivalent to (and faster than)ignore (carve side s i). In other words,take front s itruncates the sequencesat indexi, and keeps only the front part;take back s itruncates the sequencesat indexi, and keeps only the back part. The indeximust lie in the closed interval[0, length s].Time complexity: same as
split.
val drop : S.side -> 'a t -> Sek__.PublicSignature.index -> unitdrop side s iis equivalent totake (other side) s i. The indeximust lie in the closed interval[0, length s].Time complexity: same as
split.
val sub : 'a t -> Sek__.PublicSignature.index -> Sek__.PublicSignature.length -> 'a tsub s head sizeextracts the sequence segment defined by the sequences, the start indexhead, and the sizesize. The sequencesis unaffected.Time complexity: O(size + K).
Iteration
val iter : S.direction -> ('a -> unit) -> 'a t -> unititer direction f sapplies the functionfin turn to every elementxof the sequences. The parameterdirectiondetermines in what order the elements are presented. The functionfis not allowed to modify the sequenceswhile iteration is ongoing. If the flagcheck_iterator_validityis enabled (which it is, by default), then an illegal modification is detected at runtime.Time complexity: O(n), not counting the cost of the function
f.
val iteri : S.direction -> (Sek__.PublicSignature.index -> 'a -> unit) -> 'a t -> unititeri direction f sapplies the functionfin turn to every indexiand matching elementxof the sequences. The parameterdirectiondetermines in what order the elements are presented. The functionfis not allowed to modify the sequenceswhile iteration is ongoing. If the flagcheck_iterator_validityis enabled (which it is, by default), then an illegal modification is detected at runtime.Time complexity: O(n), not counting the cost of the function
f.
val iter_segments : S.direction -> 'a t -> 'a Sek__.PublicSignature.segmentsiter_segments direction s fapplies the functionfto a series of nonempty array segments whose concatenation represents the sequences. The functionfis allowed to read these array segments. When iterating backward, each segment must be traversed in reverse order. The functionfis not allowed to write these array segments. The functionfis not allowed to modify the sequenceswhile iteration is ongoing. If the flagcheck_iterator_validityis enabled (which it is, by default), then an illegal modification is detected at runtime.Time complexity: O(n/K), not counting the cost of the function
f.
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'afold_left f a sapplies the functionfin turn to each element of the sequences, in the forward direction. An accumulator is threaded through the calls tof. The functionfis not allowed to modify the sequenceswhile iteration is ongoing. Subject to this condition,fold_left f a sis equivalent toList.fold_left f a (to_list s). If the flagcheck_iterator_validityis enabled (which it is, by default), then an illegal modification is detected at runtime.Time complexity: O(n), not counting the cost of the function
f.
val fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'bfold_right f a sapplies the functionfin turn to each element of the sequences, in the backward direction. An accumulator is threaded through the calls tof. The functionfis not allowed to modify the sequenceswhile iteration is ongoing. Subject to this condition,fold_right f s ais equivalent toList.fold_right f (to_list s) a. If the flagcheck_iterator_validityis enabled (which it is, by default), then an illegal modification is detected at runtime.Time complexity: O(n), not counting the cost of the function
f.
module Iter = S.Ephemeral.IterThe submodule
Iteroffers an implementation of iterators on ephemeral sequences.
Conversion To
val to_list : 'a t -> 'a listto_list sreturns a list whose elements are the elements of the sequences.Time complexity: O(n).
val to_array : 'a t -> 'a arrayto_array sreturns a fresh array whose elements are the elements of the sequences.Time complexity: O(n).
val to_seq : S.direction -> 'a t -> 'a Stdlib.Seq.tto_seq direction sreturns a fresh sequence whose elements are the elements of the sequences, enumerated according todirection. The sequenceto_seq direction sis ephemeral: it can be consumed only once. This sequence occupies O(log n) space in memory: it is an iterator in disguise.Time complexity: the creation of a sequence costs O(1); then, demanding each element of the sequence has the same cost as a call to
Iter.get_and_move. If k elements of the resulting sequence are demanded by the user, then the total cost of producing these elements is O(k).
Conversion From
val of_list_segment : 'a -> Sek__.PublicSignature.length -> 'a list -> 'a tof_list_segment default n xscreates a new sequence out of thenfirst elements of the listxs. The listxsmust have at leastnelements.Time complexity: O(n + K).
val of_list : 'a -> 'a list -> 'a tof_list default xscreates a new sequence out of the listxs. If the length of the listxsis known, then the use ofof_list_segmentshould be preferred.Time complexity: O(n + K).
val of_array_segment : 'a -> 'a array -> Sek__.PublicSignature.index -> Sek__.PublicSignature.length -> 'a tof_array_segment default a head sizecreates a new sequence out of the array segment defined by the arraya, the start indexhead, and the sizesize. The data is copied, so the arrayacan still be used afterwards.Time complexity: O(n + K), where n, the length of the result, is equal to
size.
val of_array : 'a -> 'a array -> 'a tof_array default acreates a new sequence out of the arraya. The data is copied, so the arrayacan still be used afterwards.Time complexity: O(n + K).
val of_seq_segment : 'a -> Sek__.PublicSignature.length -> 'a Stdlib.Seq.t -> 'a tof_seq_segment default n xscreates a new sequence out of thenfirst elements of the sequencexs. The sequencexsmust have at leastnelements. It is consumed once.Time complexity: O(n + K), not counting the cost of demanding elements from the sequence
xs.
val of_seq : 'a -> 'a Stdlib.Seq.t -> 'a tof_seq d xscreates a new sequence out of the sequencexs. The sequencexsmust be finite. It is consumed once. If the length of the sequencexsis known, then the use ofof_seq_segmentshould be preferred.Time complexity: O(n + K), not counting the cost of demanding elements from the sequence
xs.
Searching
val find : S.direction -> ('a -> bool) -> 'a t -> 'afind direction p sfinds and returns the first element of the sequences, along the directiondirection, that satisfies the predicatep. If no element of the sequence satisfiesp, the exceptionNot_foundis raised.Time complexity: O(i), where
iis the index of the first element that satisfiesp, or n if no element satisfiesp. This does not count the cost of the functionp.
val find_opt : S.direction -> ('a -> bool) -> 'a t -> 'a optionfind_opt direction p sfinds and returns the first element of the sequences, along the directiondirection, that satisfies the predicatep. If no element of the sequence satisfiesp,Noneis returned.Time complexity: same as
find.
val find_map : S.direction -> ('a -> 'b option) -> 'a t -> 'b optionfind_map direction f sappliesfto each element of the sequences, along the directiondirection, and returns the first result other thanNone. If there is no such result, it returnsNone. Iffis pure, then it is equivalent tofind direction (fun o -> o <> None) (map f s).Time complexity: same as
find, not counting the cost of the functionf.
val for_all : ('a -> bool) -> 'a t -> boolfor_all p stests whether all elements of the sequencessatisfy the predicatep.Time complexity: O(i), where
iis the index of the first element that does not satisfyp, or n if every element satisfiesp. This does not count the cost of the functionp.
val exists : ('a -> bool) -> 'a t -> boolexists p stests whether some element of the sequencessatisfies the predicatep.Time complexity: O(i), where
iis the index of the first element that satisfiesp, or n if no element satisfiesp. This does not count the cost of the functionp.
val mem : 'a -> 'a t -> boolmem x sis equivalent toexists (fun y -> x = y) s.
val memq : 'a -> 'a t -> boolmemq x sis equivalent toexists (fun y -> x == y) s.
Transformation
val map : 'b -> ('a -> 'b) -> 'a t -> 'b tmap default f sapplies the functionfin turn to each element of the sequences, in the forward direction, and returns a sequence of the results. The sequencesis unaffected.Time complexity: O(n + K), not counting the cost of the function
f.
val mapi : 'b -> (Sek__.PublicSignature.index -> 'a -> 'b) -> 'a t -> 'b tmapi default f sapplies the functionfin turn to each index-and-element pair in the sequences, in the forward direction, and returns a sequence of the results. The sequencesis unaffected.Time complexity: O(n + K), not counting the cost of the function
f.
val rev : 'a t -> 'a trev sreturns a sequence whose elements are the elements of the sequences, in reverse order. The sequencesis unaffected.Time complexity: O(n + K).
val zip : 'a t -> 'b t -> ('a * 'b) tzip s1 s2is a sequence of the pairs(x1, x2), wherex1andx2are drawn synchronously from the sequencess1ands2. The lengths of the sequencess1ands2need not be equal: the length of the result is the minimum of the lengths ofs1ands2.Time complexity: O(n + K), where n denotes the length of the result sequence.
val unzip : ('a * 'b) t -> 'a t * 'b tunzip sis equivalent to(map _ fst s, map _ snd s).Time complexity: O(n + K).
val filter : ('a -> bool) -> 'a t -> 'a tfilter p sreturns a subsequence of the elements ofsthat satisfy the predicatep. The sequencesis unaffected.Time complexity: O(n + K), not counting the cost of the function
p.
val filter_map : 'b -> ('a -> 'b option) -> 'a t -> 'b tfilter_map default f sreturns the subsequence of the defined images of the elements ofsthrough the partial functionf.Time complexity: O(n + K), not counting the cost of the function
f.
Iteration over Two Sequences
val iter2 : S.direction -> ('a -> 'b -> unit) -> 'a t -> 'b t -> unititer2 direction f s1 s2repeatedly invokesf x1 x2as long as a pair of elements(x1, x2)can be drawn synchronously from the sequencess1ands2. The parameterdirectiondetermines on what side iteration must begin and in which direction it must progress. The lengths of the sequencess1ands2need not be equal: iteration stops as soon as the shortest sequence is exhausted.Time complexity: O(min(n1,n2)), where n1 and n2 denote the lengths of the arguments
s1ands2, not counting the cost of the functionf.
val iter2_segments : S.direction -> 'a t -> 'b t -> ('a, 'b) Sek__.PublicSignature.segments2iter2_segments direction s1 s2 frepeatedly invokesf seg1 seg2as long as a pair of nonempty array segmentsseg1andseg2of matching lengths can be drawn synchronously from the sequencess1ands2. The functionfis allowed to read these array segments. The parameterdirectiondetermines on what side iteration must begin and in which direction it must progress. The lengths of the sequencess1ands2need not be equal: iteration stops as soon as the shortest sequence is exhausted.Time complexity: O(min(n1,n2)/K), where n1 and n2 denote the lengths of the arguments
s1ands2, not counting the cost of the functionf.
val fold_left2 : ('c -> 'a -> 'b -> 'c) -> 'c -> 'a t -> 'b t -> 'cfold_left2is analogous toiter2 forward, with the added feature that an accumulator is threaded through the calls tof.Time complexity: same as
iter2.
val fold_right2 : ('a -> 'b -> 'c -> 'c) -> 'a t -> 'b t -> 'c -> 'cfold_right2is analogous toiter2 backward, with the added feature that an accumulator is threaded through the calls tof.Time complexity: same as
iter2.
val map2 : 'c -> ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c tmap2 d f s1 s2repeatedly invokesf x1 x2as long as a pair of elements(x1, x2)can be drawn synchronously from the sequencess1ands2, and returns the sequence of the results. Iteration is carried out in the forward direction. The lengths of the sequencess1ands2need not be equal: the length of the result is the minimum of the lengths ofs1ands2.Time complexity: O(n + K), where n denotes the length of the result, not counting the cost of the function
f.
val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> boolfor_all2 p s1 s2tests whether all pairs(x1, x2)drawn synchronously froms1ands2satisfy the predicatep. The sequencess1ands2need not have the same length: any excess elements are ignored.Time complexity: O(min(n1,n2)), where n1 and n2 denote the lengths of the arguments
s1ands2, not counting the cost of the functionp.
val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> boolexists2 p stests whether some pair(x1, x2)drawn synchronously froms1ands2satisfies the predicatep. The sequencess1ands2need not have the same length: any excess elements are ignored.Time complexity: O(min(n1,n2)), where n1 and n2 denote the lengths of the arguments
s1ands2, not counting the cost of the functionp.
Comparison
val equal : ('a -> 'b -> bool) -> 'a t -> 'b t -> boolequal p s1 s2tests whether the sequencess1ands2have the same length and all pairs(x1, x2)drawn synchronously froms1ands2satisfy the predicatep. Ifp x1 x2compares the elementsx1andx2for equality, thenequal p s1 s2compares the sequencess1ands2for equality.Time complexity: O(1) if the sequences have distinct lengths; otherwise O(i), where i is the index of the first pair that does not satisfy the predicate
p, or n if all pairs satisfyp. This does not count the cost of the functionp.
val compare : ('a -> 'b -> Sek__.PublicSignature.comparison) -> 'a t -> 'b t -> Sek__.PublicSignature.comparisonIf
cmpimplements a preorder on elements, thencompare cmpimplements the lexicographic preorder on sequences. (A preorder is an antisymmetric and transitive relation. For more details on comparison functions in OCaml, see the documentation ofArray.sort.)Time complexity: same as
equal.
Sorting
val sort : ('a -> 'a -> Sek__.PublicSignature.comparison) -> 'a t -> unitsort cmp ssorts the sequencesaccording to the preordercmp. (For more details, see the documentation ofArray.sort.)Time complexity: O(n log n + K).
The current implementation converts the data to an array and back. A future release may provide a more efficient implementation.
val stable_sort : ('a -> 'a -> Sek__.PublicSignature.comparison) -> 'a t -> unitstable_sort cmp ssorts the sequencesaccording to the preordercmp. (For more details, see the documentation ofArray.sort.) The sorting algorithm is stable: two elements that are equal according tocmpare never permuted.Time complexity: O(n log n + K).
The current implementation converts the data to an array and back. A future release may provide a more efficient implementation.
val uniq : ('a -> 'a -> Sek__.PublicSignature.comparison) -> 'a t -> 'a tuniq cmp sreturns a copy of the sequenceswhere adjacent duplicate elements have been filtered out. That is, an element is dropped if it is equal (according to the preordercmp) to its left neighbor. If the sequencesis sorted with respect tocmp, then the sequenceuniq cmp shas no duplicate elements. The sequencesis unaffected.Time complexity: O(n + K).
val merge : ('a -> 'a -> Sek__.PublicSignature.comparison) -> 'a t -> 'a t -> 'a tmerge cmp s1 s2requires the sequencess1ands2to be sorted with respect to the preordercmp. It constructs a new sequence that is a sorted copy of the sequenceconcat s1 s2. The sequencess1ands2are unaffected.Time complexity: O(n + K), where
ndenotes the sum of the lengths ofs1ands2, that is, the length of the result.
In-Place Transformation
val fill : 'a t -> Sek__.PublicSignature.index -> Sek__.PublicSignature.length -> 'a -> unitfill s i k xmodifies the sequencesby overwriting the elements in the range[i, i+k)with the elementx.Time complexity: if the sequence involves chunks that may be shared with other sequences, the complexity is O(k + k/K * log n + K in the worst case. If none of the chunks that correspond to the range
[i, i+k)were ever shared, then the cost is only O(k + log n).
val blit : 'a t -> Sek__.PublicSignature.index -> 'a t -> Sek__.PublicSignature.index -> Sek__.PublicSignature.length -> unitblit s1 i1 s2 i2 kmodifies the sequences2by overwriting the elements ofs2in the range[i2, i2+k)with the elements found in the sequences1in the range[i1, i1+k). It is permitted fors1ands2to be the same sequence; in that case, all reads appear to take place before any writes.Time complexity: same as
fill.
Miscellaneous
val format : Stdlib.Format.formatter -> int t -> unitformatis a printer for sequences of integers. It can be installed in the OCaml toplevel loop by#install_printer format. It is intended to be used only while debugging the library.
val check : 'a t -> unitIn a release build,
check sdoes nothing. In a development build, it checks that the data structure's internal invariant is satisfied.
val create : unit -> D.element tval make : Sek__.PublicSignature.length -> D.element -> D.element tval init : Sek__.PublicSignature.length -> (Sek__.PublicSignature.index -> D.element) -> D.element tval of_list_segment : Sek__.PublicSignature.length -> D.element list -> D.element tval of_list : D.element list -> D.element tval of_array_segment : D.element array -> Sek__.PublicSignature.index -> Sek__.PublicSignature.length -> D.element tval of_array : D.element array -> D.element tval of_seq_segment : Sek__.PublicSignature.length -> D.element Stdlib.Seq.t -> D.element tval of_seq : D.element Stdlib.Seq.t -> D.element t