2012-02-09 13 views
22

In chiusura, come è possibile applicare and o qualsiasi altra macro a un elenco?In clojure, come applicare "e" a un elenco?

Questo non funziona:

(apply and '(true false)) 

Perché apply non può prendere il valore di una macro.

Quindi, qual è il modo migliore per verificare se tutti gli elementi di una lista sono veri?

+0

possibile duplicato [ "ridurre" o "applicare" utilizzando le funzioni logiche in Clojure] (http://stackoverflow.com/questions/2891707/ ridurre-o-applicare-utilizzando-funzioni-logiche-in-clojure) – amalloy

risposta

33

È possibile fare questo, invece:

(every? identity '(true false)) 

Vedi this thread per ulteriori informazioni.

6

In Clojure macro non sono cose di prima classe non comporre abbastanza come funzioni, e non potete passarli ad altre funzioni, e non è possibile apply loro. Questo perché sono finiti e fatti prima che una qualsiasi applicazione venga eseguita.

Si è soliti macro avvolgere nelle funzioni di apply o passarli a funzioni

(defmacro my-macro [x y z] ...) 

(apply #(my-macro %1 %2 %3) [1 2 3]) 

(map #(my-macro) [1 2 3] [:a :b :c] [a b c]) 

il lettore anonimo-funzione macro #( rende questo così facile che macroes non essere di prima classe non è davvero un inconveniente . Basta provare a remember the first rule of macro club

+1

Ma questo approccio crollerà quando la macro riceve un numero variabile di argomenti. – viebel

+0

stai rompendo la prima regola del club macro ... sì, anche le perdite di astrazione macro :( –

0

È anche possibile fare questo: (apply = true '(true false))

0
user=> (eval `(and [email protected](list true false))) 

false 

user=> (eval `(and [email protected] (list true true 1))) 

1 

Io sono la sintassi apici e poi applicare un grosso martello per rimuovere le parentesi intorno alla raccolta e poiché ho citato che, hanno usare eval. Questo è utile se stai creando una macro e la funzione passata è "e".

quindi (list 1 2 3) slitta martellata diventa 1 2 3.

Questo è un modo, estremamente terribile, ma funziona, quindi ho capito quello che sta facendo per me che è bello. Quindi il mio clojure non è eccezionale, ma spero che questo esempio macro chiarisca le cose.

(defmacro split-my-args-then-apply-fn 
    "This is one terrible macro designed to show the use of 'and'." 
    [fun coll & args] 
    `(~fun [email protected]((apply juxt args) coll))) 

Usage (Mai):

(split-my-args-then-apply-fn 
    and 
    {:something :true :something-else false} 
    :something :something-else) 
Problemi correlati