Clojure:分离comp和部分参数

时间:2013-02-28 16:02:01

标签: clojure

假设我有一个需要两个参数的函数,并且参数的顺序会影响结果。

是否可以将第一个参数传递给partial或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)

3 个答案:

答案 0 :(得分:8)

partial只在左侧“填写”参数,因此如果您需要跳过参数,则必须使用fn

(def baz2 #(bar %1 arg2))

另请注意,comp要求其所有参数都是函数,因此quxqux2实际上是无意义的。他们应该是:

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

一般来说,Clojure核心功能会将变量最有可能改变 last ,以使comppartial更加自然。 (例如,集合参数在Clojure中几乎总是最后的,除了像into之类的东西,把它放在第一位是有意义的。)当你设计自己的函数时,你应该坚持这个约定,这样你就可以编写你的函数更容易。

答案 1 :(得分:4)

Scheme SRFI 26有一个有用的宏cut,用于插入这样的参数。

对于您减去bar

的用法就是这样
 ((cut bar <> 1) 2)
 ;=> 1
 ((comp str (cut - <> 1)) 2)
 ;=> "1"

<>符号代表要填充的广告位。

在Clojure中自己实现cut这是一项有趣的练习,但{@ 3}}来自@Baishampayan Ghose。

答案 2 :(得分: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是第一种)。

干杯!

相关问题