Anonymous Recursion in C#このトピックに関する素晴らしい議論があります。
再帰が美しく、ラムダは であり、究極の抽象化である。しかし、どうすればそれらを一緒に使うことができますか? ?ここで
// This is the combinator
public static Func<A,R> Y<A,R>(Func<Func<A,R>, Func<A,R>> f)
{
Func<A,R> g = null;
g = f(a => g(a));
return g;
}
呼び出すためのそれの使用だ:これが再び現れたので、ここでYコンビネータを使った例だ、...
ラムダは 匿名関数であり、再帰 には名前が必要です匿名の、再帰関数...
Func<int,int> exp = Y<int,int>(e => x => (x <=1) ? 1 : x * e(x - 1));
Console.WriteLine(exp(5));
あなたはYコンビネータを使用して、ちょうどデリゲートで再帰を設定しない場合、あなたはcorreを取得しないことに注意します
ct再帰。たとえば...
しかし、すべてが正常に動作します...
Console.WriteLine(badRec(5));
// Output
// 120
しかし、これを試してみてください...
Func<int,int> badRec = null;
badRec = x => (x <= 1) ? 1 : x * badRec(x - 1);
Func<int,int> badRecCopy = badRec;
badRec = x => x + 1;
Console.WriteLine(badRec(4));
Console.WriteLine(badRecCopy(5));
// Output
// 5
// 25
何ですか?ラインbadRec = x => x + 1;
後、あなたが実際に持っているデリゲートがこれです
あなたが見
、...
badRecCopy = x => (x <= 1) ? 1 : x * ((x+1)-1);
ので、badRecは、私たちが(4+1=5)
を期待している1で値をインクリメントされますが、badRecCopyは今、実際に戻っていますほぼ確実に期待していなかった値(5*((5+1)-1)
の正方形。
あなたはYコンビネータを使用する場合は、予想通り、それは動作します...
Func<int,int> goodRec = Y<int,int>(exp => x => (x <=1) ? 1 : x * exp(x - 1));
Func<int,int> goodRecCopy = goodRec;
そして、あなたは、あなたが期待するものを手に入れます。
goodRec = x => x + 1;
Console.WriteLine(goodRec(4));
Console.WriteLine(goodRecCopy(5));
// Output
// 5
// 120
あなたはY-combinator(PDFリンク)についての詳細を読むことができます。
VS2008からの正確な苦情がある:ローカル変数「ビルド」を前に初期化されない場合がありますアクセスする。 – Matt