Frage

Ist es möglich, McCarthys amb-Operator zu implementieren für nicht-deterministische Auswahl in C #?

Offenbar fehlt .NET Fortsetzung Unterstützung aber yield return nützlich sein könnte. Wäre die .NET-Sprachen wie F # in andere statisch möglich sein?

War es hilfreich?

Lösung

Ja, tut yield return eine Form der Fortsetzung. Obwohl für viele nützlichen Fälle stellen Linq funktionelle Operatoren, die es Ihnen ermöglichen, zusammen einen faulen Sequenz-Generator zu anschließen, so in der Tat in C # 3 es nicht notwendig ist yield return zu verwenden, so viel (außer, wenn mehr Linq-Stil Erweiterungen der eigenen Hinzufügen zu Plug Lücken in der Bibliothek, zB Zip, ausklappen).

Im Beispiel Faktorisierung wir eine ganze Zahl mit brutalen Gewalt. Im Wesentlichen kann das gleiche Beispiel in C # mit dem eingebauten in Linq Operatoren durchgeführt werden:

var factors = Enumerable.Range(2, 100)
        .Join(Enumerable.Range(2, 100), 
              n => 1, n => 1, (i, j) => new { i, j })
        .First(v => v.i*v.j == 481);

Console.WriteLine("Factors are " + factors.i + ", " + factors.j);

Hier werden die Ausgangspunkte sind meine beiden Anrufe, Enumerable.Range welche eingebaut ist zu Linq, aber man könnte sich als implementieren:

IEnumerable<int> Range(int start, int stop)
{
    for (int n = start; n < stop; n++)
        yield return n;
}

Es gibt zwei ungeradee Parameter, die n => 1, n => 1 Parameter Join. Ich bin 1 als Schlüsselwert Kommissionierung für Join zu verwenden, wenn gleichen Artikel auf, daher werden alle Kombinationen passen und so bekomme ich jede Kombination von Zahlen aus den Bereichen zu testen.

Dann drehe ich das Wertepaar in eine Art Tupel (ein anonymer Typ) mit:

(i, j) => new { i, j })

Schließlich nehme ich die erste solche Tupel für die mein Test erfüllt ist:

.First(v => v.i*v.j == 481);

Aktualisieren

Der Code innerhalb des Aufrufs First braucht nicht nur ein kurzer Testausdruck. Es kann eine ganze Menge zwingenden Code sein, die „Neustart“ werden muss, wenn der Test nicht bestanden:

.First(v => 
       {
           Console.WriteLine("Aren't lambdas powerful things?");

           return v.i*v.j == 481;
       );

So ist der Teil des Programms, das möglicherweise mit unterschiedlichen Werten geht in diesem Lambda neu gestartet werden muss. Jedes Mal, wenn das Lambda selbst will mit unterschiedlichen Werten neu zu starten, es ist einfach falsch zurück -. Das äquivalent Aufruf amb ohne Argumente

Andere Tipps

Das ist keine Antwort auf Ihre Frage, aber es kann Sie bekommen, was Sie wollen.

amb wird für nichtdeterministischen Computing verwendet. Wie Sie vielleicht wissen, ist Prolog eine nichtdeterministische Sprache des Begriffs der Vereinigung unter Verwendung von Werten an Variablen zu binden (im Grunde, was amb landet tun).

Es ist eine Implementierung dieser Funktion in C #, genannt YieldProlog. Wie Sie vielleicht erraten, ist die Ausbeute Betreiber eine wichtige Voraussetzung dafür.

http://yieldprolog.sourceforge.net/

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top