Aproveitando a preguiça de Seq em F #

Vale lembrar que a preguiça que vem junto com o tipo de dados Seq <‘a> do F # (o equivalente IEnumerable <T>) tem vantagens além de apenas criar sequências infinitas.

Ao usar Seq, todas as transformações que você faz a sequência são sequenciais, de modo que ocorrem sequencialmente para cada elemento, em vez de processar todos os elementos antes de passar para a próxima etapa no pipeline de processamento.

Exemplo:
vamos pegar um filtro numérico simples, que permitirá apenas números divisíveis por 2:

let filter1 i = i % 2 = 0

E então temos outra etapa no processo, vamos fazer a mesma coisa para números divisíveis por 3:

let filter2 i = i % 3 = 0

Agora, se você os encadear usando List.filter da seguinte forma:
[1 .. 20] |> List.filter filter1 |> List.filter filter2

O que acontece nos bastidores é que para cada número na lista (1 a 20) o filtro 1 é executado, a lista resultante é alimentada para o filtro 2, então o processo é algo como

1 % 2 = 0
2 % 2 = 0
3 % 2 = 0
4 % 2 = 0
...
20 % 2 = 0

Seguido por

2 % 3 = 0
4 % 3 = 0
6 % 3 = 0
8 % 3 = 0
...
20 % 3 = 0

Produzindo uma lista final de [6; 12; 18]

Agora, se a mesma coisa for feita com um Seq (e a função Seq.filter) assim:
{1 .. 20} |> Seq.filter filter1 |> Seq.filter filter2
Você obtém o seguinte:

1 % 2 = 0
2 % 2 = 0
2 % 3 = 0
3 % 2 = 0
4 % 2 = 0
4 % 3 = 0
...

Isso também funciona se sua fonte for uma Lista e você usar as funções Seq como:
[1 .. 20] |> Seq.filter filtro1 |> Seq.filtro filtro2

Além disso, a mesma coisa acontece em C # quando você usa IEnumerables e iteradores