2013-02-28 30 views
3

說我有一個函數需要兩個參數,並且參數的順序影響結果。Clojure:分離comp和部分參數

是否有可能第一個參數傳遞到部分或補償功能和其他拋開,就像這樣:

(defn bar [arg1 arg2] (- arg1 arg2)) 
(def baz (partial (bar arg1))) 
(def qux (comp str (bar arg1))) 

(baz arg2) 
(qux arg2) 

如果我想通過ARG2進入功能,我可以做類似這個?

(def baz2 (partial (bar _ arg2))) 
(def qux2 (comp str (bar _ arg2))) 

(baz arg1) 
(qux arg1) 

回答

5

partial只是「填補」左側的參數,所以如果你需要跳過參數必須使用fn

(def baz2 #(bar %1 arg2)) 

還要注意comp要求所有的參數是功能,讓您的quxqux2實際上是無稽之談。他們應該是:

(def qux (comp str baz)) 
(def qux2 (comp str baz2)) 

一般來說,Clojure的核心功能將會把最有可能改變最後使組成與comppartial更自然的變量。 (例如,Clojure中的集合參數幾乎總是最後的,除了像into這樣的東西,它首先是有意義的。)當你設計你自己的函數時,你應該堅持這個約定,以便你可以更容易地編寫你的函數。

+0

謝謝你讓我們知道這個約定。 – leontalbot 2013-02-28 17:43:32

2

這是我在一個REPL了:

user=> (defn bar [arg1 arg2] (- arg1 arg2)) 
#'user/bar 
user=> (def baz (partial bar 5)) 
#'user/baz 
user=> (def qux (comp str baz)) 
#'user/qux 
user=> (baz 2) 
3 
user=> (qux 2) 
"3" 

這是最接近我可以從你的第一個範例中得到。

對於第二個例子,也許一個簡單的DEFN比部分DEF更好:

user=> (defn baz2 [x] (bar x 5)) 
#'user/baz2 
user=> (def qux2 (comp str baz2)) 
#'user/qux2 
user=> (baz2 2) 
-3 
user=> (qux2 2) 
"-3" 

我建議你啓動一個REPL,並自己嘗試一下,這是去發現語言的第二個最好的方式我知道(TDD是第一個)。

乾杯!

3

Scheme SRFI 26有一個有用的宏cut這樣的插槽參數。

用法是,像這樣爲你減去bar

((cut bar <> 1) 2) 
;=> 1 
((comp str (cut - <> 1)) 2) 
;=> "1" 

<>符號表示插槽填補。

在Clojure中實現cut是一個有趣的練習,而here is one port由@Baishampayan Ghose完成。

+0

有趣的謝謝! – leontalbot 2013-02-28 17:42:17