2016-02-03 6 views
-2

В JavaScript ES6 вкус, была введена функция генератора поэтому такого рода конструкций возможны:F # функциональный генератор эквивалент

var fib = function *(max) { 
    var x = 0, y = 1, tmp = 1; 
    while (tmp<max) { 
    yield tmp; 
    x = y; 
    y = tmp; 
    tmp = x + y; 
    } 
} 
var fibgen = fib(3000); 

Здесь fibgen является генератор, который будет производить меньше, чем 3000 чисел Фибоначчи.

Что было бы эквивалентной конструкцией в F #?

LE: Я не ищу algorithm for Fibonacci series. Но для некоторой функции генератора, которая лениво испускала бы значение при итерации по ней.

+1

где ваше решение? –

+0

Я очень новичок в функциональном программировании. Все, о чем я могу думать, - это императивная реализация. И этого я не хочу. – Adrian

+1

Вы должны уточнить (путем редактирования вопроса) то, что вы ищете. Эквивалентная конструкция в F # практически идентична с использованием выражения последовательности и изменяемых переменных. Вы хотите знать идиоматический подход F #? Или идиоматический функциональный подход? – TheQuickBrownFox

ответ

3

См. this MSDN article for lazily evaluated sequences in F#. Возможное решение данной проблемы, используя Seq.unfold:

let fibTo limit = 
    Seq.unfold (fun (a, b) -> Some (b, (b, a+b))) (0I, 1I) 
    |> Seq.takeWhile (fun i -> i <= limit) 

Первая строка создает последовательность Фибоначчи, лениво оценены. Второй ограничивает его. I - буква для целых чисел произвольной длины. Тест:

fibTo 3000I |> Seq.iter (printf "%A ") 

Выход: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584

fibTo (pown 10I 30) 

Возвращает последовательность Fibonnaci до 898923707008479989274290850145 - последнее значение не больше, чем 10^30 - если оценивается, что далеко.