8

皆さんが元気であることを願っています。Harbor で固定小数点Y コンビネータを実装していますが、問題が発生しています。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から無限までの制限を回避しています。

ここまでは問題なくコンパイルできますが、外側のブロックの変数にアクセスしようとすると、Harbor に顔を蹴られてしまいます。

Y コンビネーターの実装をテストするために、フィボナッチ数列の単純な実装を適用しようとしましたが、パラメーターを受け取るGブロックを返し、パラメーターを受け取るブロックを暗黙的に返すと、使用できなくなりNGコンパイラーは「外側のコードブロック変数に到達できません。」

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

これにより、ブロックをカリー化することもできます。私の質問は、ハーバーでブロック内の外部変数にアクセスするにはどうすればよいですか?

4

1 に答える 1