С кодом возникает несколько проблем.
Начиная с этой линией
| fibl n = fibl [n]
Вы сопрягая для списка целых чисел, в двух предыдущих строках. Таким образом, ваша функция должна иметь такой список, как вход. Однако в приведенной выше строке вы принимаете этот список целых чисел n
и вызываете свою функцию рекурсивно с помощью n
, упакованного внутри другого списка fibl [n]
. Обратите внимание, что это совпадение генерирует бесконечный цикл при фиксированном!
Еще одна проблема заключается в том, что ваш последний матч является избыточным, так как вышеупомянутое совпадение будет захватывать все входные данные, в результате чего ваш последний матч будет соответствовать последнему.
У вас также есть некоторые ошибки в последнем матче. Обратите внимание, что ваша функция возвращает свой результат в виде списка одиночных элементов. В вашей функции f
вы пытаетесь добавить результат своей функции fibl
(т. Е. Список int), что возможно. Здесь вам либо нужно «вытащить» номер из списка, либо сделать что-то совершенно другое.
Поскольку вы пытаетесь сгенерировать список чисел фибоначчи, я бы предположил, что вы делаете что-то совершенно другое, так как ваш текущий подход генерирует только список из двух чисел фибоначчи. Я бы предложил начать с наивного решения; с функцией, которая будет генерировать n-й номер фибоначчи, а затем сгенерировать список, применяя эту функцию снова и снова.
Некоторые примеры
В соответствии с просьбой, вот некоторые примеры того, как можно было бы сделать это наивно.
Сначала мы определим функцию, которая будет генерировать n-е число фибоначчи.
fun fib 0 = 0
| fib 1 = 1
| fib n = fib (n-1) + fib (n-2)
Эта функция может затем легко быть отображены с помощью списка чисел, генерируя список тех конкретных чисел Фибоначчи
- val fibLst = map fib [0,1,2,3,4,5,6,7,8];
val fibLst = [0,1,1,2,3,5,8,13,21] : int list
Однако мы также можем создать функцию, которая будет генерировать список 0. ..n, а затем применить функцию fib к этому списку.
fun genFib n = List.tabulate (n, fib);
или без списка.табулирования функции
fun genFib1 n =
let
fun loop 0 acc = fib 0 :: acc
| loop m acc = loop (m-1) (fib m :: acc)
in
loop (n-1) []
end
Очевидно, что функция выдумки может быть реализована гораздо лучше, и наши производящий список функций можно просто воспользоваться, как создаются число следующего Фибоначи. Вы заметите, что функция ниже работает намного быстрее при создании списка, содержащего первые 40 номеров фибоначчи.
fun genFib2 n =
let
fun loop 0 _ _ acc = rev acc
| loop m f_1 f_2 acc = loop (m-1) f_2 (f_1 + f_2) (f_2 :: acc)
in
loop (n-1) 0 1 [0]
end
выше есть некоторые проблемы с размером целого числа в SML (вы можете создать 44-е число Фибоначчи, но не сорок пятый). Таким образом, мы можем расширить функции Фибо использовать произвольной точности целое IntInf, вместе с идеей сверху
fun fibInf n : IntInf.int =
let
fun loop 0 f_1 _ = f_1
| loop m f_1 f_2 = loop (m-1) f_2 (f_1 + f_2)
in
loop n 0 1
end
Сейчас это как «быстрый» и возможно произвести первые 100 чисел Фибоначчи, или более
fun genFibInf n = List.tabulate (n, fibInf);
- genFibInf 1000;
val it = [0,1,1,2,3,5,8,13,21,34,55,89,...] : IntInf.int list
- List.nth(it, 700);
val it =
8747081495575284620397841301757132734236724096769738107423043259252750#
: IntInf.int
the '| fibl n = fibl [n] 'предназначался для работы, только принимая целые числа и отображая их в списке, думаю, я забыл, что, если вы не укажете тип, он подумает, что он может принимать любые значения и отображать их в список. Но теперь, когда вы говорите это, это имеет смысл, думаю, я не совсем проснулся, когда я это сделал ... большое спасибо –
Не могли бы вы придумать возможное решение для меня, чтобы учиться? –
уверен, se обновление сообщение –