2010-02-24 64 views
4

的condp條款是這樣的:Clojure:是否可以創建一個宏來在單個condp子句中創建這兩個元素?

 "plet" (make-adj 2 "ète") 
     "iet" (make-adj 2 "ète") 
     "nin" (make-adj 1 "gne") 

我要的條件添加到make-adj函數調用,而不在一行中兩次重複的條件。我想,輪流這個宏:

(test-make-adj "plet" 2 "ète") 
(test-make-adj "iet" 2 "ète") 
(test-make-adj "nin" 1 "gne") 

進入這個:

 "plet" (make-adj 2 "ète" "plet") 
     "iet" (make-adj 2 "ète" "iet") 
     "nin" (make-adj 1 "gne" "nin") 

回答

4

condp具有內置的功能來支持這樣的事情:

(condp #(if (= %1 %2) %1) condition 
    "plet" :>> #(make-adj 2 "ète" %) 
    "iet" :>> #(make-adj 2 "ète" %) 
    "nin" :>> #(make-adj 1 "gne" %)) 

#(if (= %1 %2) %1)是一個二元函數檢查它的參數是否相等,如果它們是返回第一個參數,否則返回nil

:>>使得它使得評估在condition上的謂詞和例如"plet"被傳遞給#(make-adj ...)函數。通過上述謂詞,這意味着如果(= "plet" condition)true,則"plet"被傳遞給#(make-adj ...)。有關更多信息,請參閱(doc condp)

如果仍然感覺像太多打字,你可以創建一個輔助函數:

(defn make-adj* [n s] 
    (fn [c] (make-adj n s c)) 

然後使用它像這樣:

(condp #(if (= %1 %2) %1) condition 
    "plet" :>> (make-adj* 2 "ète") 
    ...) 
2

首先一個功能,使condp條款

(defn test-make-adj [x num y] 
    `(~x (make-adj ~num ~y ~x))) 

之一,那麼宏組裝條款轉化爲condp表達式

(defmacro adj-condp [pred expr & clauses] 
    `(condp ~pred ~expr 
    [email protected](mapcat test-make-adj clauses))) 

PS:我不是在我的REPL,所以我不能對此進行測試,請編輯:)

+1

我在幾個補丁的代碼已經編輯。除了刪除兩個小錯誤之外,我用'mapcat'替換了'(應用concat(map ...))'並根據樣式調整了縮進。希望你確定。 – 2010-02-25 00:58:03

+0

是啊,多數民衆贊成在:) – 2010-02-25 01:18:11

相關問題