Давайте Seq.zip две последовательности F #, одна представленная списком, а другая - Seq.filter, примененная к бесконечной последовательности:
Seq.initInfinite (fun i -> i)
|> Seq.filter ((>) 3)
|> Seq.zip ["A";"B"]
возвращается как ожидалось
val it : seq<string * int> = seq [("A", 0); ("B", 1)]
Тем не менее,
Seq.initInfinite (fun i -> i)
|> Seq.filter ((>) 2)
|> Seq.zip ["A";"B"]
зависает при попытке получить несуществующего третьего члена, который может передать Seq.filter и в конечном итоге взорвать fsi:
Error: Enumeration based on System.Int32 exceeded System.Int32.MaxValue.
хотя другой аргумент, представленный списком букв, намекает на то, что для выполнения функции zip со спецификацией функции будет достаточно двух отфильтрованных элементов.
Если мы обратимся к Haskell для сравнения реализации, то эквивалент
zip ["A","B"] (filter (<2) [0..])
завершается без проблем, давая
[("A",0),("B",1)]
Поскольку поведение реализации Haskell кажется интуитивно правильным, каково оправдание наблюдаемого поведения реализации F # Seq.zip?
UPDATE:
Я не заметил, что Haskell
zip (filter (<2) [0..]) ["A","B"]
не завершается аналогично F #.
Итог: Невозможно реализовать функцию Zip, способную архивировать последовательности определенной и неопределенной длины в порядке, не зависящем от порядка аргументов. Реализация F # Zip просто предпочитает инвариант к поведению порядка аргументов по сравнению с зависимым от порядка аргументов Haskell.