Объявление типа seq<'a>
является псевдонимом типа для System.Collections.Generic.IEnumerable<'a>
. Этот интерфейс предоставляет перечислитель, с помощью которого мы можем перебирать коллекцию, все функции более высокого уровня также будут зависеть от этих интерфейсов. Поэтому итерация последовательности с помощью метода MoveNext()
и свойства Current
должна быть наиболее эффективным способом.
let zip (s1 : seq<_>) (s2 : seq<_>) =
use e1 = s1.GetEnumerator()
use e2 = s2.GetEnumerator()
let rec loop () = seq{
if e1.MoveNext() && e2.MoveNext() then
yield e1.Current, e2.Current
yield! loop() }
loop()
zip [1..3] [11..14] |> Seq.toList
// val it : (int * int) list = [(1, 11); (2, 12); (3, 13)]
Seq.zip [1..3] [11..14] |> Seq.toList
// val it : (int * int) list = [(1, 11); (2, 12); (3, 13)]
Вложенная вспомогательная функция прекрасно инкапсулирует рекурсию.