2011-09-07 25 views
6

Sto tentando di ritardare i vari calcoli. Ho funzioni del seguente modulo,Argomenti funzione più tipi

(defn a-fn [a b] 
    (let [a (if (fn? a) 
      a 
      #(identity a)) 

     b (if (fn? b) 
      b 
      #(identity b))] 
    (+ (a) (b)))) 

questo mi permette di passare un-fn, un valore o una funzione che restituisce il valore,

(a-fn 1 2)  
(defn x [] 1)  
(defn y [] 2)  
(a-fn x y) 
(a-fn x 2) 

quello che faccio è costruire una lista di funzioni (come quello sopra) per operare su alcuni dati, fns può usare altri fns per recuperare i loro argomenti o in alcuni casi le cose non cambiano e vengono assegnati valori come argomenti. Mi stavo chiedendo c'è un modo migliore per ottenere questo tipo di comportamento?

risposta

2

Ci potrebbe essere un più elegante modo per fare quello che vuoi, ma ecco almeno una versione più generica di esso:

(defn delayed [reducer & fs] 
    (apply reducer (for [f fs] (if (fn? f) (f) f)))) 

(def a-fn (partial delayed +)) 

Così delayed prende una funzione arbitraria e un elenco di funzioni/valori. Se espande tutti gli arg e poi applica loro la funzione. Poi usiamo partial per definire il a-fn utilizzando +:

user=> (a-fn 1 2) 
3 
user=> (a-fn (constantly 1) 2) 
3 
user=> (a-fn (constantly 1) 2 4) 
7 

In alternativa, potrebbe avere senso per delayed per restituire una funzione piuttosto che usare parziale. Nota sicuro quale è meglio.

Un nome migliore di "ritardo" è il benvenuto :)

6

È possibile utilizzare delay e force:

user=> (defn a-fn [a b] (+ (force a) (force b))) 
#'user/a-fn 
user=> (a-fn 1 2) 
3 
user=> (def x (delay 1)) 
#'user/x 
user=> (def y (delay 2)) 
#'user/y 
user=> (a-fn x y) 
3 
user=> (a-fn x 2) 
3 

Se si cerca qualcosa di simile (delay (prn :hello) 1) per testare se il calcolo è fatto, si noti che la stampa l'oggetto Delay lo forza; quindi (def x (delay ...)) è sicuro, ma digitando un semplice (delay ...) nel prompt REPL non lo è.

+0

Nizza. Hai dimenticato il ritardo/la forza. –

Problemi correlati