Anonymous Recursion in C# hat eine tolle Diskussion zu diesem Thema.
Rekursion ist schön und lambdas sind die ultimative Abstraktion. Aber wie kann sie zusammen verwendet werden? Lambda-Ausdrücke sind anonyme Funktionen und Rekursion erfordert Namen ...
Da dieser wieder aufgetaucht, hier ist ein Beispiel für die Y-Combinator der Verwendung:
// 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;
}
Hier ist eine Nutzung der es sich um eine nennen anonym, rekursive Funktion ...
Func<int,int> exp = Y<int,int>(e => x => (x <=1) ? 1 : x * e(x - 1));
Console.WriteLine(exp(5));
Sie werden feststellen, dass, wenn Sie und die Rekursion nur mit dem Delegierten setzen nicht die Y-Combinator aufbrauchen, bekommt man nicht corre ct Rekursion. Zum Beispiel ...
// This is BAD. Do not do this!
Func<int,int> badRec = null;
badRec = x => (x <= 1) ? 1 : x * badRec(x - 1);
Aber alles funktioniert ...
Console.WriteLine(badRec(5));
// Output
// 120
Aber versuchen Sie diese ...
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
Was?!?
Sie sehen, nach der Zeile badRec = x => x + 1;
, der Delegierte Sie tatsächlich haben dies ...
badRecCopy = x => (x <= 1) ? 1 : x * ((x+1)-1);
So badRec den Wert um 1 erhöht wird, die wir (4+1=5)
erwarten, aber badRecCopy nun eigentlich die Rückkehr Quadrat des Wertes (5*((5+1)-1)
was wir fast sicher nicht erwartet haben.
Wenn Sie die Y-Combinator verwenden, wird es wie erwartet ...
Func<int,int> goodRec = Y<int,int>(exp => x => (x <=1) ? 1 : x * exp(x - 1));
Func<int,int> goodRecCopy = goodRec;
Und Sie bekommen, was Sie erwarten.
goodRec = x => x + 1;
Console.WriteLine(goodRec(4));
Console.WriteLine(goodRecCopy(5));
// Output
// 5
// 120
Sie können mehr über die Y-combinator (PDF-Link) lesen.
Die genaue Beschwerde von VS2008 ist: Lokale Variable ‚build‘ vor initialisiert möglicherweise nicht zugreifen. – Matt