如果需要,clojure可以评估混合arity函数链并返回部分函数吗?

时间:2012-08-11 23:41:07

标签: clojure partial lambda combinators arity

假设你有三个arity 1,2和3的函数,如下所示:

(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)))))

返回arity 2的一个重要功能?

我正在考虑创建一个宏,它可以采用上面的简单函数定义,并将它们扩展为可以返回部分结果的多元函数。如果已经有内置或惯用的方法来实现这一点,我不想创建宏。

以下是扩展宏对上述函数的期望:

(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)))

1 个答案:

答案 0 :(得分: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

然而,似乎更像是你想要做一些涉及自动调整的事情(虽然,我再也不认为我完全理解),为此我不知道任何预先存在的事情内置方式。