访问块内的外部变量和 Y 组合器
Access outer variable inside a block and Y-combinator
希望你们一切都好。我正在 Harbor 中实现定点 Y-combinator,我遇到了一些麻烦。那么,Y 组合器可以通过 lambda 演算 定义为:
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 到无限的限制。
直到这一次,它编译得很好,但是当我试图访问一个外部块的变量时,Harbor 踢我的脸!
为了测试 Y 组合器的实现,我尝试应用一个简单的斐波那契数列实现,但是当我 return 一个接收参数 G
并隐式 return 的块时一个接收参数 N
、G
的块对我来说变得不可用,编译器告诉我 "Outer codeblock variable is out of reach".
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 中访问块内的外部变量?
在 Harbour、Clipper 和基于 xBase 的编程语言中,块 never 可以参考
到父块的变量。块不是闭包。我们可以通过
创建本地存储并在内部块中使用它们:
Function TestOuterScope
Local accA
Local bAdd := { |A| accA := A, { |B| accA + B } }
Return Eval( Eval( bAdd, 10 ), 20 )
希望你们一切都好。我正在 Harbor 中实现定点 Y-combinator,我遇到了一些麻烦。那么,Y 组合器可以通过 lambda 演算 定义为:
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 到无限的限制。
直到这一次,它编译得很好,但是当我试图访问一个外部块的变量时,Harbor 踢我的脸!
为了测试 Y 组合器的实现,我尝试应用一个简单的斐波那契数列实现,但是当我 return 一个接收参数 G
并隐式 return 的块时一个接收参数 N
、G
的块对我来说变得不可用,编译器告诉我 "Outer codeblock variable is out of reach".
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 中访问块内的外部变量?
在 Harbour、Clipper 和基于 xBase 的编程语言中,块 never 可以参考 到父块的变量。块不是闭包。我们可以通过 创建本地存储并在内部块中使用它们:
Function TestOuterScope
Local accA
Local bAdd := { |A| accA := A, { |B| accA + B } }
Return Eval( Eval( bAdd, 10 ), 20 )