2014-10-03 2 views
2

Я могу написать ленивый Фибоначчи в Clojure так:Ленивый Фибоначи в Рубине

(def fib (lazy-cat [1 1] (map +' fib (rest fib)))) 

и я пытаюсь (безуспешно), чтобы записать его в Ruby, как это:

fib = Enumerator.new do |yielder| 
    yielder << 1 << 1 
    fib.zip(fib.drop(1)).map do |a,b| 
    yielder << (a + b) 
    end 
end 

В упрощенный случай, это работает:

fib = Enumerator.new do |yielder| 
    yielder << 1 << 1 
    puts "here" 
end 
puts fib.take(2).inspect 
puts fib.drop(1).take(1).inspect 

, но это не делает:

fib = Enumerator.new do |yielder| 
    yielder << 1 << 1 
    puts "here" 
    fib.drop(1) 
end 
puts fib.take(2).inspect 
puts fib.drop(1).take(1).inspect 

Почему этот последний пример дает мне ошибку SystemStackError: stack level too deep?

+0

'drop' - это функция, основанная на перечислителе. Попробуйте получить доступ к элементу внутри перечислителя по методу oldschool по индексу. – mudasobwa

ответ

3

Во-первых, fib в рубиновой версии не эквивалентно версии clojure. В версии clojure это функция.

И Enumerable#zip, Enumerable#drop и Enumerable.take не являются ленивыми, если вы явно не указали его. Если вы не вызываете Enumerable#lazy, они возвращают Array (жадно потребляя все элементы, вызывая исключение).

def fib 
    Enumerator.new do |yielder| 
    yielder << 1 << 1 
    fib.lazy.zip(fib.lazy.drop(1)).each do |a,b| 
     yielder << a + b 
    end 
    end 
end 

fib.take(2) 
# => [1, 1] 
fib.lazy.drop(1).take(1).to_a # Note: `lazy`, `to_a`. 
# => [1] 
fib.take(4) 
# => [1, 1, 2, 3] 
+0

Вау, мне удивительно, что вам нужно использовать '' .lazy'''. Код Clojure выше создает var и используется следующим образом: '' '(принять 2 (drop 1 fib))' ''. Функция будет создана с '' 'defn'''. Спасибо за ответ - именно то, что я искал! – bmaddy

+1

Возможно, предупреждение о неэффективности было бы хорошим. Уже 'fib.take (20)' сбой для меня с 'невозможно создать волокно (FiberError)'. Я пришел сюда из [нового вопроса, используя это] (https://stackoverflow.com/q/48492051/1672429). –

Смежные вопросы