模組 Stdlib.Seq

module Seq: Seq

type 'a t = unit -> 'a node 

類型為 'a t 的序列 xs 是類型為 'a 的元素的延遲列表。透過執行函式應用 xs() 來查詢此類序列。此函式應用返回一個節點,允許呼叫者確定序列是空的還是非空的,並且在後一種情況下,可以取得其頭部和尾部。

type 'a node = 
| Nil
| Cons of 'a * 'a t

一個節點可以是 Nil,這表示序列為空,也可以是 Cons (x, xs),這表示 x 是序列的第一個元素,而 xs 是序列的其餘部分。

消耗序列

本節中的函式會部分或完全消耗其參數(一個序列)

類似地,在消耗兩個序列的函式中,可以區分兩個群組

消耗兩個序列的函式可以應用於兩個長度不同的序列:在這種情況下,會忽略較長序列中多餘的元素。(可能會要求一個多餘的元素,即使該元素未使用。)

本節中的函式都不是惰性的。這些函式是消耗者:它們會強制執行一些計算。

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 xsNone

如果 xs 為非空,則 uncons xsSome (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 _ 的第一個元素(如果存在這樣的元素),而 yf 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 會針對從序列 xsys 同步提取的每一對元素 (x, y),依次呼叫 f x y

如果序列 xsys 的長度不同,則一旦其中一個序列耗盡,迭代就會停止;另一個序列中多餘的元素會被忽略。

僅當序列 xsys 中至少有一個是有限的時,迭代才會終止。

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 會針對從序列 xsys 同步提取的每一對元素 (x, y),依次呼叫 f _ x y

類型為 'a 的累加器會透過對 f 的呼叫來傳遞。

如果序列 xsys 的長度不同,則一旦其中一個序列耗盡,迭代就會停止;另一個序列中多餘的元素會被忽略。

僅當序列 xsys 中至少有一個是有限的時,迭代才會終止。

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 會判斷從序列 xsys 同步提取的所有元素對 (x, y) 是否都滿足 p x y

如果序列 xsys 的長度不同,則一旦其中一個序列耗盡,迭代就會停止;另一個序列中多餘的元素會被忽略。特別是,如果 xsys 為空,則 for_all2 p xs ys 為 true。這就是 for_all2equal 不同的地方:只有當 xsys 具有相同的長度時,equal eq xs ys 才能為 true。

序列 xsys 中至少有一個必須是有限的。

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 會判斷從序列 xsys 同步提取的某些元素對 (x, y) 是否滿足 p x y

如果序列 xsys 的長度不同,則一旦其中一個序列耗盡,迭代必須停止;另一個序列中多餘的元素會被忽略。

序列 xsys 中至少有一個必須是有限的。

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 會判斷序列 xsys 是否逐點相等。

序列 xsys 中至少有一個必須是有限的。

val compare : ('a -> 'b -> int) -> 'a t -> 'b t -> int

如果函式 cmp 定義了元素上的預序,則 compare cmp xs ys 會根據詞典預序比較序列 xsys

如需關於比較函式的更多詳細資訊,請參閱 Array.sort

序列 xsys 中至少有一個必須是有限的。

建構序列

本節中的函式是惰性的:也就是說,它們傳回的序列中的元素僅在需要時才會計算。

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)

val unfold : ('b -> ('a * 'b) option) -> 'b -> 'a t

unfold 從步進函式和初始狀態建構序列。

如果 f uNone,則 unfold f u 為空序列。如果 f uSome (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 是一個無限序列,其元素為 xf xf (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

mapimap 類似,但會將函數 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; ...],其中 a1f a0 x0a2f 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 xsxs 的前 n 個元素的序列。

如果 xs 的元素少於 n 個,則 take n xs 等同於 xs

n 必須是非負數。

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

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。這在調試或測試時很有用,可以確保一個序列最多被取用一次。

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 是序列 xsys 的串聯。

其元素為 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_mapflat_map 的別名。

val zip : 'a t -> 'b t -> ('a * 'b) t

zip xs ys 是從序列 xsys 同步提取的配對 (x, y) 序列。

如果序列 xsys 的長度不同,則只要其中一個序列耗盡,該序列就會結束;另一個序列中多餘的元素會被忽略。

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) 是從序列 xsys 同步提取的。

如果序列 xsys 的長度不同,則只要其中一個序列耗盡,該序列就會結束;另一個序列中多餘的元素會被忽略。

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 的第一個元素,依此類推的序列。

當其中一個序列 xsys 耗盡時,interleave xs ys 會繼續處理另一個序列的剩餘部分。

val sorted_merge : ('a -> 'a -> int) -> 'a t -> 'a t -> 'a t

如果序列 xsys 根據總預序 cmp 排序,則 sorted_merge cmp xs ys 是透過合併序列 xsys 獲得的排序序列。

如需關於比較函式的更多詳細資訊,請參閱 Array.sort

val product : 'a t -> 'b t -> ('a * 'b) t

product xs ys 是序列 xsys 的笛卡爾積。

對於 xs 的每個元素 xys 的每個元素 y,配對 (x, y) 會作為 product xs ys 的一個元素出現一次。

配對出現的順序未指定。

序列 xsys 不需要是有限的。

序列 xsys 必須是持久的。

val map_product : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t

序列 map_product f xs ys 是序列 xsys 的笛卡爾積通過 f 的圖像。

對於 xs 的每個元素 xys 的每個元素 y,元素 f x y 會作為 map_product f xs ys 的一個元素出現一次。

這些元素出現的順序未指定。

序列 xsys 不需要是有限的。

序列 xsys 必須是持久的。

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

splitunzip 的別名。

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 開始並向上計數的無限整數序列。