輸出和輸出
在序列工作流程中,yield
將單個專案新增到正在構建的序列中。 (在 monadic 術語中,它是 return
。)
> seq { yield 1; yield 2; yield 3 }
val it: seq<int> = seq [1; 2; 3]
> let homogenousTup2ToSeq (a, b) = seq { yield a; yield b }
> tup2Seq ("foo", "bar")
val homogenousTup2ToSeq: 'a * 'a -> seq<'a>
val it: seq<string> = seq ["foo"; "bar"]
yield!
(發音為 yield bang )將另一個序列的所有項插入到正在構建的序列中。或者,換句話說,它附加一個序列。 (關於 monad,它是 bind
。)
> seq { yield 1; yield! [10;11;12]; yield 20 }
val it: seq<int> = seq [1; 10; 11; 12; 20]
// Creates a sequence containing the items of seq1 and seq2 in order
> let concat seq1 seq2 = seq { yield! seq1; yield! seq2 }
> concat ['a'..'c'] ['x'..'z']
val concat: seq<'a> -> seq<'a> -> seq<'a>
val it: seq<int> = seq ['a'; 'b'; 'c'; 'x'; 'y'; 'z']
由序列工作流建立的序列也是惰性的,這意味著序列的專案在需要之前不會被實際評估。強制專案的幾種方法包括呼叫 Seq.take
(將前 n 個專案拉入序列),Seq.iter
(將函式應用於每個專案以執行副作用)或 Seq.toList
(將序列轉換為列表)。將此與遞迴相結合是 yield!
真正開始閃耀的地方。
> let rec numbersFrom n = seq { yield n; yield! numbersFrom (n + 1) }
> let naturals = numbersFrom 0
val numbersFrom: int -> seq<int>
val naturals: seq<int> = seq [0; 1; 2; ...]
// Just like Seq.map: applies a mapping function to each item in a sequence to build a new sequence
> let rec map f seq1 =
if Seq.isEmpty seq1 then Seq.empty
else seq { yield f (Seq.head seq1); yield! map f (Seq.tail seq1) }
> map (fun x -> x * x) [1..10]
val map: ('a -> 'b) -> seq<'a> -> 'b
val it: seq<int> = seq [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]