Я надеюсь, что вы все в порядке. Я реализую Y-комбинатор с фиксированной точкой в Harbour, и у меня с ним возникают проблемы. Что ж, Y-комбинатор можно определить с помощью лямбда-исчисления как:
Y = (λh.λF.F(λ x.((h(h))(F))(x))) (λh.λF.F(λ x.((h(h))(F))(x)))
Я пытаюсь применить мемоизацию с помощью Y-combinator по вопросам производительности. Моя текущая реализация:
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
становится недоступным для меня, и компилятор говорит мне, что «Внешняя переменная кодового блока вне досягаемости».
Function Main
Local bFib := YMem( { |G| ;
{ |N| ;
Iif( N == 0, 1, Iif( N == 1, 1, Eval( G, N - 1 ) + Eval( G, N - 2) ) );
} ;
} )
Return
Это также позволило бы мне каррировать блоки. Мой вопрос: как я могу получить доступ к внешней переменной внутри блока в Harbour?