Я не могу воспроизвести вашу проблему.Когда я загружаю ваш код, я вижу это:
# List.length (listify result1 10000 (fun x -> x));;
- : int = 10000
# List.length (listify result1 26831 (fun x -> x));;
- : int = 26831
Возможно, ваша система более ограничена в ресурсах, чем моя.
Позвольте мне просто сказать, что обычный способ кодирования хвостовой рекурсивной функцииэто построить список в обратном порядке, а затем обратить его в конце.Это может выглядеть примерно так:
let listify2 st n =
let rec ilist accum st k =
match st with
| Eos -> List.rev accum
| StrCons (m, a) ->
if k = 1 then List.rev (m :: accum)
else ilist (m :: accum) (a ()) (k - 1)
in
if n = 0 then []
else ilist [] st n
У вас все еще есть проблема, что listify не завершается, если вы запрашиваете больше элементов, чем есть в потоке.Возможно, было бы лучше ввести метод обнаружения конца потока и возврата Eos в этой точке.Например, функция filter
может принимать функцию, которая возвращает три возможных значения (элемент должен быть отфильтрован, элемент не должен быть отфильтрован, поток должен завершиться).