Как указал Федор, в третьем случае match
есть синтаксическая ошибка, потому что вы на самом деле не передаете параметр в функцию fibonacciRecursive
.Однако, если вы исправите это, передав x
, вы обнаружите, что ваша функция выдает StackOverflowException
при выполнении.Это потому, что вы рекурсивно пытаетесь сгенерировать всю последовательность для каждого значения.
Очень простое решение для Фибоначчи в F # выглядит следующим образом:
let rec fib = function
| 0 -> 0
| 1 -> 1
| n -> fib (n - 1) + fib (n - 2)
Однако, это также в конечном итоге приведет к переполнению стека, поскольку вызовы не являются "хвостовыми рекурсивными", то естьрекурсия - это не последнее, что происходит в функции (в этом случае добавление - последнее, что должно происходить).Вы можете сделать хвостово-рекурсивное решение, отложив выполнение каждого элемента с продолжением, так что рекурсивный вызов находится в хвостовой позиции:
let fib n =
let rec fib cont = function
| n when n < 2 -> cont n
| n -> (n - 1) |> fib (fun x -> (n - 2) |> fib (fun y -> cont (x + y)))
fib id n
Это немного сложно следовать, и это часто требуетнекоторое время, чтобы привыкнуть думать о написании функций таким образом.Вот версия, использующая двойные обратные галочки, чтобы разрешить описательным именам параметров продолжения, если это помогает понять, что происходит:
let fib n =
let rec fib cont = function
| n when n < 2 ->
cont n
| n ->
(n - 1) |> fib (fun ``fib (n-1)`` ->
(n - 2) |> fib (fun ``fib (n-2)`` ->
cont (``fib (n-1)`` + ``fib (n-2)``)))
fib id n