2012-03-29 8 views

risposta

12

È possibile implementare un combinatore Y utilizzando call/cc, as described here. (! Molte grazie a John Cowan per menzionare questo post pulito) Citando quel post, ecco l'implementazione di Oleg:

Corollario 1. combinatore Y tramite call/cc - Y Combinator senza un auto-esplicita richiesta.

(define (Y f) 
    ((lambda (u) (u (lambda (x) (lambda (n) ((f (u x)) n))))) 
    (call/cc (call/cc (lambda (x) x))))) 

Qui, abbiamo usato un fatto che

((lambda (u) (u p)) (call/cc call/cc)) 

e

((lambda (u) (u p)) (lambda (x) (x x))) 

sono osservativamente equivalenti.

+1

Incredibile, esattamente quello che voglio. Molte grazie. – day

+0

@wberry Ho deciso di trovare un modo per citare lo snippet di codice che si spera sia più "corretto" - compatibile. –

+0

Molto bene, grazie. – wberry

6

La tua domanda è un po 'vaga. In particolare, sembra che tu voglia un sistema che modella le chiamate ricorsive senza effettuare chiamate ricorsive, usando call/cc. Risulta, tuttavia, che è possibile modellare le chiamate ricorsive senza effettuare chiamate ricorsive e senza utilizzare call/cc. Ad esempio:

#lang racket 

(define (factorial f n) 
    (if (= n 0) 1 (* n (f f (- n 1))))) 

(factorial factorial 3) 

Questo può sembrare un imbroglio, ma è la base del combinatore Y. Forse puoi rafforzare il set di restrizioni a cui stai pensando?

P.S .: se questo è compito, per favore citatemi!

+0

Bene, ho già conosciuto questo trucco per fare la ricorsione. Quello che mi chiedo è se esiste un modo non auto-referente che usa call/cc per definire una funzione ricorsiva, diciamo il tuo 'fattoriale '. Questo non è un esercizio per i compiti a casa! Grazie. – day

+1

@plmday La soluzione di John non è già autoreferenziale. Che altro avresti bisogno di 'call/cc'? –

+0

@ SamTobin-Hochstadt Bene, è, 'f' si riferisce a se stesso, non è vero?Voglio vedere fino a che punto possiamo andare con 'call/cc', in particolare, data la sua abilità, possiamo utilizzarlo per simulare il modo usuale o insolito di definire una funzione ricorsiva. – day

2

Ho paura che lo call/cc non abbia molto a che fare con questo. Esistono solo due modi per definire una funzione ricorsiva:

  • Supponiamo che la lingua consenta la definizione di funzioni ricorsive; Ad esempio, un corpo di funzione può fare riferimento alla funzione di chiusura, oppure il corpo di una funzione f può fare riferimento a una funzione g il cui corpo fa riferimento a f. In questo caso, beh, basta scriverlo nel solito modo.
  • Se la tua lingua vieta entrambi, ma ha ancora funzioni di prima classe e lambda, puoi usare uno fixed-point combinator come il combinatore Y. Scrivi la tua funzione in modo che consideri come argomento aggiuntivo una funzione che intende rappresentare il passo ricorsivo; ogni posto in cui dovresti recitare, invece invochi quell'argomento.

Così per factorial, si scrive così:

(define (factorial-step recurse n) 
    (if (zero? n) 
     1 
     (* n (recurse (- n 1))))) 

La magia del combinatore Y è che si costruisce la funzione recurse che sarebbe alimentato factorial-step.