したがって、Yコンビネーターとは何かを覚えています(覚えていないが、これは固定小数点コンビネーターまたはY g = g Y gです)。 彼の数学的な表記からいくつかの問題があります:それはシーケンスggg ... g Y gを生成します。次の各ステップでは、前の計算の結果とコンビネータからキャプチャされたコンテキストのみを使用できます。
アイデアは、自己適用機能に依存しないYコンビネータを作成することです。
理論的には、入力として次のデータを受け取る必要があります:再帰の関数、引数リストを変更する関数、およびこのリストの初期状態。
さらに、再帰関数は前の値とこのステップで変更された引数のリストを取得する必要があります。
まず、Haskellで実装を試みます。
Y functor argtracker args = functor(Y functor argtracker(agtracker args))args;
さて、今、階乗を計算することができます:
fac N =
Y
(\ prev-> \ i-> i = 0の場合、1 else prev * i)
(\ i-> i-1)
N;
次に、4の階乗を計算します。
組み合わせ置換を完了すると、以下が得られます。
fac 4 =
(\ prev-> 4-> if 4 = 0 then 1 else else prev * i)
((\ prev-> 3-> if 3 = 0 then 1 1 else prev * i)
((\ prev-> 2-> if 2 = 0 then 1 else prev * i)
((\ prev-> 1-> if 1 = 0 then 1 else prev * i)
((\ prev-> 0-> if 0 = 0 then 1 else prev * i)))))
今崩壊:
fac 4 =
(\ prev-> 4-> 4 = 0の場合、1 else else prev * 4)
((\ prev-> 3-> if 3 = 0 then 1 else prev * 3)
((\ prev-> 2-> if 2 = 0 then 1 else prev * 2)
((\ prev-> 1-> if 1 = 0 then 1 1 else prev * 1)
(1)))))
fac 4 =
(\ prev-> 4-> 4 = 0の場合、1 else else prev * 4)
((\ prev-> 3-> if 3 = 0 then 1 else prev * 3)
((\ prev-> 2-> if 2 = 0 then 1 else prev * 2)
(1 * 1)))))
fac 4 =
(\ prev-> 4-> 4 = 0の場合、1 else else prev * 4)
((\ prev-> 3-> if 3 = 0 then 1 else prev * 3)
(2 *(1 * 1))))
fac 4 =
(\ prev-> 4-> if 4 = 0 then 1 else else prev * i)
3 *(2 *(1 * 1))
fac 4 = 4 * 3 * 2 * 1 * 1
うまくいくようです:)
-第15コライダーの時代の6月3日2000年と9年目を更新しました。
最近、開発されたインターフェイスには特定の制限が導入されているという結論に達しました:次の反復のデータが現在の反復の結果によって決定される場合、後者はインクリメンターとファンクターで2回計算する必要があります。
したがって、このようなバージョンのYコンビネーターが開発されました。
Yファンクターデータ=
ファンクター
(\ newdata-> Y functor newdata)
データ;
Lisp:
(defun Y(ファンクターデータ)
(funcallファンクター
(ラムダ(新しいデータ)
(Yファンクターの新しいデータ))))
これにより、ファンクターで次の反復のデータを選択できます。つまり、再帰は線形だけでなく、ツリー状にもなります。