2010-08-14 8 views
5

Facendo la Y-Combinator per una singola funzione argomento come fattoriale o Fibonacci in Clojure è ben documentato: http://rosettacode.org/wiki/Y_combinator#ClojureApplicando l'Y-Combinator a una funzione ricorsiva con due argomenti in Clojure?

La mia domanda è - come si fa a farlo per una funzione a due argomenti come questo getter per esempio?

(Assunzione qui è che io voglio risolvere questo problema in modo ricorsivo e questo codice clojure non idiomatica è lì deliberatamente per un altro motivo)

[Versione y-Combinator non]

(defn get_ [n lat] 
    (cond 
     (empty? lat)() 
     (= 0 (- n 1)) (first lat) 
     true (get_ (- n 1) (rest lat)))) 

(get_ 3 '(a b c d e f g h i j)) 
+0

'(= 0 (- n 1))' è davvero un modo elaborato di dire '(= n 1)'. Perché la quarta e la quinta riga rientrano più del terzo, a proposito? – Svante

+0

C'è qualche ragione specifica per rendere questo getter basato su 1? – Svante

risposta

4

Il numero di args non cambia nulla in quanto lo args è apply 'd. Hai solo bisogno di cambiare la struttura del get_:

 
(defn get_ [f] 
    (fn [n lat] 
    (cond 
     (empty? lat)() 
     (= 1 n) (first lat) 
     :else (f (dec n) (next lat))))) 

(defn Y [f] 
    ((fn [x] (x x)) 
    (fn [x] 
    (f (fn [& args] 
      (apply (x x) args)))))) 
 
user=> ((Y getf) 3 '(a b c d e f g h i j)) 
c 
2

E' d essere abbastanza semplice.

Diciamo che hai una funzione H:

(def H 
    (fn [x] 
     (fn [x y] 
       (stuff happens)))) 

Quindi si applica la stessa ol' Y-Combinator:

((Y H) 4 5) 

Dove 4 e 5 sono argomenti che si desidera passare a H

Il combinatore essenzialmente "gestisce" la funzione di primo livello in H, non quella che sta facendo il duro lavoro (quella con arity 2, qui).

Problemi correlati