2013-02-28 31 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