2012-08-11 34 views
5

假設你有元數1,2的三種功能和3如下:clojure能否評估一系列混合函數並在需要時返回部分函數?

(defn I [x] x) 
(defn K [x y] x) 
(defn S [x y z] (x z (y z))) 

是否Clojure的專門制定了評價的評價函數或成語:

(I K S I I) as (I (K (S (I (I))))) 

返回元數2的parital功能?

我在考慮創建一個宏,它可以將上面的簡單函數定義並將它們展開爲可以返回部分結果的多元函數。如果已經有內置或慣用的方法來實現這一點,我不想創建宏。

這裏是擴展宏想什麼爲實現上述功能:

(defn I 
    ([x] I x) 
    ([x & more] (apply (I x) more))) 

(defn K 
    ([x] (partial K x)) 
    ([x y] x) 
    ([x y & more] (apply (K x y) more))) 

(defn S 
    ([x] (partial S x)) 
    ([x y] (partial S x y)) 
    ([x y z] (x z (y z))) 
    ([x y z & more] (apply (S x y z) more))) 
+0

剛剛發現這一點,並認爲它*可能*是完美的,如果沒有別的,至少有幫助... http://alfredodinapoli.wordpress.com/2011/03/16/a-bit-of -clojure-magic-and-high-order-functions-are-served/ – 2012-08-12 22:39:13

回答

5

我不知道我完全理解你正在嘗試做的,但做這種的comp功能很有用「功能鏈」你似乎在談論。例如:

user> ((comp vec rest list) 1 2 3 4 5) 
=> [2 3 4 5] 

即相當於:

user> (vec (rest (list 1 2 3 4 5))) 
=> [2 3 4 5] 

在你的情況,如果你有列表(I K S I I),並希望將其評價爲(I (K (S (I (I))))),我會用(reduce comp ...),但你可以也使用(apply comp ...)

user> ((reduce comp [vec rest list]) 1 2 3 4 5) 
=> [2 3 4 5] 
user> ((apply comp [vec rest list]) 1 2 3 4 5) 
=> [2 3 4 5] 

您還可能有興趣在->->>宏。這些宏將它們的參數順序嵌套到下一個參數中。宏將嵌套到下一個表達式的第一個位置,而->>宏將嵌套到下一個表達式的最後一個位置。如果「接下來的事情」是一個函數,兩者都會表現相同,並形成(function nested-things-so-far)的表達式,並繼續。

真的,例子是最好的:

(-> 1 (+ 10) (- 100) inc) 
;//Expands to... 
(inc (- (+ 1 10) 100)) 
;//Evaluating in the REPL... 
user> (-> 1 (+ 10) (- 100) inc) 
=> -88 

(->> 1 (+ 10) (- 100) inc) 
;//Expands to... 
(inc (- 100 (+ 10 1))) 
;//Evaluating in the REPL... 
user> (-> 1 (+ 10) (- 100) inc) 
=> 90 

然而,它似乎更喜歡你想要做的事,涉及自動鑽營(雖然,再次,我不認爲我完全理解),併爲我不知道任何預先存在的內置方式。

+0

謝謝你的回答。因爲我是clojure和lisp類型編程的新手,所以我需要一段時間來思考它是否可以簡化我所做的工作。有時候我知道我想做什麼,但不知道它叫什麼,甚至當我有一個好的搜索術語時,clojure的結果是非常有限的。只要發現我正在嘗試做的事情可能被稱爲「自動咖喱」是一個很大的幫助。 – dansalmo 2012-08-12 02:10:45

相關問題