module Seq: Seq
type'a
t =unit -> 'a node
類型為 'a t
的序列 xs
是類型為 '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
無法再使用。
val uncons : 'a t -> ('a * 'a t) option
如果 xs
為空,則 uncons xs
為 None
。
如果 xs
為非空,則 uncons xs
為 Some (x, ys)
,其中 x
是序列的頭部,而 ys
是序列的尾部。
val length : 'a t -> int
length xs
是序列 xs
的長度。
序列 xs
必須是有限的。
val iter : ('a -> unit) -> 'a t -> unit
iter f xs
會針對序列 xs
的每個元素 x
,從左到右依次呼叫 f x
。
僅當序列 xs
是有限的時,才會終止。
val fold_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc
fold_left f _ xs
會針對序列 xs
的每個元素 x
,從左到右依次呼叫 f _ x
。
類型為 'a
的累加器會透過對 f
的呼叫來傳遞。
僅當序列 xs
是有限的時,才會終止。
val iteri : (int -> 'a -> unit) -> 'a t -> unit
iteri f xs
會針對序列 xs
中位於索引 i
的每個元素 x
,依次呼叫 f i x
。
僅當序列 xs
是有限的時,才會終止。
iteri f xs
等效於 iter (fun (i, x) -> f i x) (zip (ints 0) xs)
。
val fold_lefti : ('acc -> int -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc
fold_lefti f _ xs
會針對序列 xs
中位於索引 i
的每個元素 x
,依次呼叫 f _ i x
。
類型為 'b
的累加器會透過對 f
的呼叫來傳遞。
僅當序列 xs
是有限的時,才會終止。
fold_lefti f accu xs
等效於 fold_left (fun accu (i, x) -> f accu i x) accu (zip (ints 0) xs)
。
val for_all : ('a -> bool) -> 'a t -> bool
for_all p xs
會判斷序列 xs
的所有元素 x
是否滿足 p x
。
序列 xs
必須是有限的。
val exists : ('a -> bool) -> 'a t -> bool
exists xs p
會判斷序列 xs
中是否至少有一個元素 x
滿足 p x
。
序列 xs
必須是有限的。
val find : ('a -> bool) -> 'a t -> 'a option
find p xs
會傳回 Some x
,其中 x
是序列 xs
中滿足 p x
的第一個元素(如果存在這樣的元素)。
如果不存在這樣的元素,則傳回 None
。
序列 xs
必須是有限的。
val find_index : ('a -> bool) -> 'a t -> int option
find_index p xs
會傳回 Some i
,其中 i
是序列 xs
中滿足 p x
的第一個元素的索引(如果存在這樣的元素)。
如果不存在這樣的元素,則傳回 None
。
序列 xs
必須是有限的。
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
必須是有限的。
val find_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b option
與 find_map
相同,但是謂詞會應用於元素的索引(從 0 開始計數)作為第一個引數,而元素本身作為第二個引數。
序列 xs
必須是有限的。
val iter2 : ('a -> 'b -> unit) -> 'a t -> 'b t -> unit
iter2 f xs ys
會針對從序列 xs
和 ys
同步提取的每一對元素 (x, y)
,依次呼叫 f x y
。
如果序列 xs
和 ys
的長度不同,則一旦其中一個序列耗盡,迭代就會停止;另一個序列中多餘的元素會被忽略。
僅當序列 xs
和 ys
中至少有一個是有限的時,迭代才會終止。
iter2 f xs ys
等效於 iter (fun (x, y) -> f x y) (zip xs ys)
。
val fold_left2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc
fold_left2 f _ xs ys
會針對從序列 xs
和 ys
同步提取的每一對元素 (x, y)
,依次呼叫 f _ x y
。
類型為 'a
的累加器會透過對 f
的呼叫來傳遞。
如果序列 xs
和 ys
的長度不同,則一旦其中一個序列耗盡,迭代就會停止;另一個序列中多餘的元素會被忽略。
僅當序列 xs
和 ys
中至少有一個是有限的時,迭代才會終止。
fold_left2 f accu xs ys
等效於 fold_left (fun accu (x, y) -> f accu x y) (zip xs ys)
。
val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
for_all2 p xs ys
會判斷從序列 xs
和 ys
同步提取的所有元素對 (x, y)
是否都滿足 p x y
。
如果序列 xs
和 ys
的長度不同,則一旦其中一個序列耗盡,迭代就會停止;另一個序列中多餘的元素會被忽略。特別是,如果 xs
或 ys
為空,則 for_all2 p xs ys
為 true。這就是 for_all2
和 equal
不同的地方:只有當 xs
和 ys
具有相同的長度時,equal eq xs ys
才能為 true。
序列 xs
和 ys
中至少有一個必須是有限的。
for_all2 p xs ys
等效於 for_all (fun b -> b) (map2 p xs ys)
。
val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
exists2 p xs ys
會判斷從序列 xs
和 ys
同步提取的某些元素對 (x, y)
是否滿足 p x y
。
如果序列 xs
和 ys
的長度不同,則一旦其中一個序列耗盡,迭代必須停止;另一個序列中多餘的元素會被忽略。
序列 xs
和 ys
中至少有一個必須是有限的。
exists2 p xs ys
等效於 exists (fun b -> b) (map2 p xs ys)
。
val equal : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
如果函式 eq
定義了元素上的相等性,則 equal eq xs ys
會判斷序列 xs
和 ys
是否逐點相等。
序列 xs
和 ys
中至少有一個必須是有限的。
val compare : ('a -> 'b -> int) -> 'a t -> 'b t -> int
如果函式 cmp
定義了元素上的預序,則 compare cmp xs ys
會根據詞典預序比較序列 xs
和 ys
。
如需關於比較函式的更多詳細資訊,請參閱 Array.sort
。
序列 xs
和 ys
中至少有一個必須是有限的。
本節中的函式是惰性的:也就是說,它們傳回的序列中的元素僅在需要時才會計算。
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))
。
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)
。
n
為負數,則引發 Invalid_argument
。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
。
val repeat : 'a -> 'a t
repeat x
是無限序列,其中元素 x
無限重複。
repeat x
等效於 cycle (return x)
。
val forever : (unit -> 'a) -> 'a t
forever f
是無限序列,其中每個元素都透過函式呼叫 f()
產生(按需)。
例如,forever Random.bool
是隨機位元的無限序列。
forever f
等效於 map f (repeat ())
。
val cycle : 'a t -> 'a t
cycle xs
是由序列 xs
的無限重複次數組成的無限序列。
如果 xs
是空序列,則 cycle xs
也為空。
對序列 cycle xs
取用(一個前綴),可能會導致序列 xs
被取用多次。因此,xs
必須是持久的。
val iterate : ('a -> 'a) -> 'a -> 'a t
iterate f x
是一個無限序列,其元素為 x
、f x
、f (f x)
等等。
換句話說,它是函數 f
的軌跡,從 x
開始。
本節中的函式是惰性的:也就是說,它們傳回的序列中的元素僅在需要時才會計算。
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
。
val filter : ('a -> bool) -> 'a t -> 'a t
filter p xs
是序列 xs
中滿足 p x
的元素 x
所組成的序列。
換句話說,filter p xs
是序列 xs
,其中不包含 p x
為 false 的元素 x
。
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
。
val take : int -> 'a t -> 'a t
take n xs
是 xs
的前 n
個元素的序列。
如果 xs
的元素少於 n
個,則 take n xs
等同於 xs
。
n
必須是非負數。
n
為負數,則引發 Invalid_argument
。val drop : int -> 'a t -> 'a t
drop n xs
是序列 xs
,其中不包含其前 n
個元素。
如果 xs
的元素少於 n
個,則 drop n xs
為空。
n
必須是非負數。
drop
是惰性的:僅當需要 drop n xs
的第一個元素時,才會要求序列 xs
的前 n+1
個元素。因此,drop 1 xs
*不* 等同於 tail xs
,後者會立即查詢 xs
。
n
為負數,則引發 Invalid_argument
。val take_while : ('a -> bool) -> 'a t -> 'a t
take_while p xs
是序列 xs
的最長前綴,其中每個元素 x
都滿足 p x
。
val drop_while : ('a -> bool) -> 'a t -> 'a t
drop_while p xs
是序列 xs
,其中不包含前綴 take_while p xs
。
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
必須是持久的。
val memoize : 'a t -> 'a t
序列 memoize xs
與序列 xs
具有相同的元素。
無論 xs
是暫時性的還是持久性的,memoize xs
都是持久性的:即使它被查詢多次,也最多只會查詢 xs
一次。
序列 memoize xs
的構造在內部依賴於模組 Lazy
提供的暫停。這些暫停 *不是* 線程安全的。因此,序列 memoize xs
*不能* 由多個線程同時查詢。
exception Forced_twice
當多次查詢 Seq.once
返回的序列(或其後綴)時,會引發此例外。
val once : 'a t -> 'a t
序列 once xs
與序列 xs
具有相同的元素。
無論 xs
是暫時性的還是持久性的,once xs
都是一個暫時性序列:它最多只能被查詢一次。如果它(或其後綴)被查詢多次,則會引發例外 Forced_twice
。這在調試或測試時很有用,可以確保一個序列最多被取用一次。
once xs
或其後綴被查詢多次,則引發 Forced_twice
。val transpose : 'a t t -> 'a t t
如果 xss
是一個矩陣(一個行序列),則 transpose xss
是矩陣 xss
的列序列。
矩陣 xss
的行不需要具有相同的長度。
矩陣 xss
不需要是有限的(在任何方向上)。
矩陣 xss
必須是持久的。
val append : 'a t -> 'a t -> 'a t
append xs ys
是序列 xs
和 ys
的串聯。
其元素為 xs
的元素,後跟 ys
的元素。
val concat : 'a t t -> 'a t
如果 xss
是一個序列的序列,則 concat xss
是其串聯。
如果 xss
是序列 xs0; xs1; ...
,則 concat xss
是序列 xs0 @ xs1 @ ...
。
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
的別名。
val zip : 'a t -> 'b t -> ('a * 'b) t
zip xs ys
是從序列 xs
和 ys
同步提取的配對 (x, y)
序列。
如果序列 xs
和 ys
的長度不同,則只要其中一個序列耗盡,該序列就會結束;另一個序列中多餘的元素會被忽略。
zip xs ys
等同於 map2 (fun a b -> (a, b)) xs ys
。
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)
。
val interleave : 'a t -> 'a t -> 'a t
interleave xs ys
是從 xs
的第一個元素開始,接著是 ys
的第一個元素,依此類推的序列。
當其中一個序列 xs
和 ys
耗盡時,interleave xs ys
會繼續處理另一個序列的剩餘部分。
val sorted_merge : ('a -> 'a -> int) -> 'a t -> 'a t -> 'a t
如果序列 xs
和 ys
根據總預序 cmp
排序,則 sorted_merge cmp xs ys
是透過合併序列 xs
和 ys
獲得的排序序列。
如需關於比較函式的更多詳細資訊,請參閱 Array.sort
。
val product : 'a t -> 'b t -> ('a * 'b) t
product xs ys
是序列 xs
和 ys
的笛卡爾積。
對於 xs
的每個元素 x
和 ys
的每個元素 y
,配對 (x, y)
會作為 product xs ys
的一個元素出現一次。
配對出現的順序未指定。
序列 xs
和 ys
不需要是有限的。
序列 xs
和 ys
必須是持久的。
val map_product : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
序列 map_product f xs ys
是序列 xs
和 ys
的笛卡爾積通過 f
的圖像。
對於 xs
的每個元素 x
和 ys
的每個元素 y
,元素 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)
。
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)
。
val split : ('a * 'b) t -> 'a t * 'b t
split
是 unzip
的別名。
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)
。
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
被取用兩次,並且導致函式 f
被應用到列表中的每個元素兩次。因此,f
應該是純粹且低成本的。此外,xs
應該是持久且低成本的。如果不是這種情況,請使用 partition p (memoize xs)
。
分配器 (dispenser) 是一個序列的表示方式,其型別為 unit -> 'a option
的函式。每次調用此函式時,它會回傳序列的下一個元素。當沒有更多元素時,它會回傳 None
。分配器具有可變的內部狀態,因此是短暫的:它所代表的序列最多只能被取用一次。
val of_dispenser : (unit -> 'a option) -> 'a t
of_dispenser it
是由分配器 it
產生的元素所構成的序列。它是一個短暫的序列:它最多只能被取用一次。如果需要持久的序列,請使用 memoize (of_dispenser it)
。
val to_dispenser : 'a t -> unit -> 'a option
to_dispenser xs
是在序列 xs
上的一個新的分配器。
此分配器具有可變的內部狀態,並且沒有鎖保護;因此,它不能被多個執行緒同時使用。
val ints : int -> int t
ints i
是從 i
開始並向上計數的無限整數序列。