Domanda

E 'possibile implementare amb-operatore di McCarthy per scelta non deterministica in C #?

A quanto pare manca il supporto .NET continuazione ma yield return potrebbe essere utile. Questo sarebbe possibile in altri .NET-lingue statiche come F #?

È stato utile?

Soluzione

Sì, yield return fa una forma di continuità. Anche se per molti casi utili, LINQ offre agli operatori funzionali che consentono di collegare insieme un generatore di sequenza pigro, quindi in realtà in C # 3 non è necessario utilizzare yield return tanto (tranne quando l'aggiunta di ulteriori estensioni in stile Linq del proprio per colmare le lacune nella biblioteca, quale ZIP, Unfold).

Nell'esempio abbiamo fattorizzare un intero con la forza bruta. In sostanza lo stesso esempio in C # può essere fatto con il built-in operatori Linq:

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);

Ecco i punti di partenza sono i miei due chiamate a Enumerable.Range, che è built-in per Linq, ma si potrebbe implementare te stesso come:

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

Ci sono due parametri dispari, il n => 1, parametri n => 1 a Join. Rilevo 1 come il valore della chiave per Join da utilizzare quando corrispondenza gli oggetti, quindi tutte le combinazioni corrisponderanno e così ho arrivare a testare ogni combinazione di numeri da gamme.

Poi mi giro la coppia di valori in una sorta di tupla (un tipo anonimo) con:

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

Infine, prendo il primo tale tupla per il quale il mio test è soddisfatto:

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

Aggiorna

Il codice all'interno della chiamata a First non deve essere solo una breve espressione di prova. Può essere un bel po 'di codice imperativo che deve essere "riavviato" se il test fallisce:

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

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

Quindi la parte del programma che ha bisogno potenzialmente essere riavviato con valori diversi va in quel lambda. Ogni volta che lambda vuole riavviare stesso con valori diversi, restituisce semplicemente false -. L'equivalente di chiamare amb senza argomenti

Altri suggerimenti

Questa non è una risposta alla tua domanda, ma si può ottenere quello che vuoi.

AMB viene utilizzato per il calcolo non deterministico. Come forse sapete, Prolog è un linguaggio non deterministico utilizzando il concetto di unificazione per associare i valori alle variabili (fondamentalmente ciò che amb finisce per fare).

C'è un'implementazione di questa funzionalità in C #, chiamato YieldProlog. Come avete indovinato, l'operatore resa è un requisito importante per questo.

http://yieldprolog.sourceforge.net/

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top