2015-03-16 8 views
8

Надеюсь, вам все будет в порядке. Я реализую фиксированную точку Y-combinator в Гавани, и у меня возникают проблемы с ним. Ну, Y-комбинатор может быть определено лямбда-исчисления как:Доступ к внешней переменной внутри блока и Y-combinator

Y = (λh.λF.F(λ x.((h(h))(F))(x))) (λh.λF.F(λ x.((h(h))(F))(x)))

Я пытаюсь применить запоминанием с Y-комбинатора вопросами производительности. Моя текущая реализация является:

Function YMem(bF, aCache) 
    Local xAnswer 
    If !lCache ; lCache := { } ; EndIf 
    Return { |Arg| Iif(aCache[ Arg ] ; 
     , /* then  */ aCache[ Arg ]; 
     , /* otherwise */ aCache[ Arg ] := ; 
      Eval(Eval(bF, { |N| Eval(Eval(YMem, bF, aCache), N) }), Arg)) } 

В принципе, я не могу использовать операторы внутри блоков, но я могу использовать выражение, и она работает просто отлично. Я избегаю бесконечной рекурсии и предела, проходящего через 0 до бесконечности.

До сих пор он компилируется просто отлично, но когда я пытаюсь получить доступ к переменной внешнего блока, Харбор пинает меня в Лице!

Чтобы проверить выполнение Y-комбинатор, я пытаюсь применить простую реализацию Фибоначчи последовательности, но когда я возвращаю блок, который принимает параметр G и неявно возвращает блок, который принимает параметр N, G becames недоступен для меня и компилятор говорит мне, что «Наружная переменная блокировки недоступна».

Function Main 
    Local bFib := YMem({ |G| ; 
     { |N| ; 
      Iif(N == 0, 1, Iif(N == 1, 1, Eval(G, N - 1) + Eval(G, N - 2))); 
     } ; 
    }) 
    Return 

Это также позволило бы мне каррировать блоки. Мой вопрос: как я могу получить доступ к внешней переменной внутри блока, в Гавани?

+0

@vittore Извините? –

ответ

4

В языках порта, Clipper и xBase, блоки never может ссылаться на на переменную родительского блока. Блоки не замыкаются. Мы можем достичь этого с помощью , создавая локальные хранилища и используя их во внутренних блоках:

Function TestOuterScope 
    Local accA 
    Local bAdd := { |A| accA := A, { |B| accA + B } } 
    Return Eval(Eval(bAdd, 10), 20) 

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

  • Нет связанных вопросов^_^