Сообщение об ошибке относится к отсутствующему конструктору типа данных, Cons
. Это отсутствует, потому что у вас нет объявления типа данных в упомянутом коде. Возможно, вам не хватает строки, которая выглядит следующим образом:
datatype 'a seq = Cons of 'a * (unit -> 'a seq)
Если вы вставите это объявление вверху вашего кода, вы получите новое сообщение об ошибке:
! val list = fibs(10)
! ^^^^
! Type clash: expression of type
! int seq
! cannot have type
! 'a -> 'b
Вы получаете эту ошибку, потому что вы определяете fibs
как последовательность целых чисел, но в последней строке вы ссылаетесь на fibs
как на функцию, которая принимает, предположительно, количество элементов, которые вы хотите извлечь из этой последовательности , В определении последовательности нет ничего плохого. Вот как бы я отформатировал первую часть кода:
val fibs =
let fun fibs_help (n, next) = Cons (n, fn () => fibs_help (next, n+next))
in fibs_help(0, 1)
end
Чтобы извлечь конкретное количество элементов из этой бесконечной последовательности, например, в ограниченный список требует немного больше работы. Напишите функцию take (i, s)
, которая создает список первых i
элементов последовательности s
:
fun take (0, ...) = ...
| take (i, Cons (n, subseq_f)) = ...
Базовый случай - это когда вы хотите получить список нулевых элементов из любой последовательности. Подумайте, нужно ли / и нужно сопоставить шаблон с входной последовательностью и каков результат этого тривиального случая. Рекурсивный случай - это когда вы хотите получить список из одного или нескольких элементов из любой последовательности; Сделайте это, включив один элемент n
в результат, и решите проблему с той же структурой, но с размером меньше, используя take
, i
и subseq_f
.
Как только эта функция заработает, вы можете использовать ее, чтобы получить список из десяти элементов:
val ten_first = take (10, fibs)