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

dan*_*lmo 5 lambda clojure combinators partial arity

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

(defn I [x] x)
(defn K [x y] x)
(defn S [x y z] (x z (y z)))
Run Code Online (Sandbox Code Playgroud)

clojure是否具有用于评估的评估函数或习语:

(I K S I I) as (I (K (S (I (I)))))
Run Code Online (Sandbox Code Playgroud)

返回arity 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)))
Run Code Online (Sandbox Code Playgroud)

Omr*_*ein 5

我不确定我完全理解你想要做什么,但是这个comp功能对于你正在谈论的这种"功能链"很有用.例如:

user> ((comp vec rest list) 1 2 3 4 5)
=> [2 3 4 5]
Run Code Online (Sandbox Code Playgroud)

这相当于:

user> (vec (rest (list 1 2 3 4 5)))
=> [2 3 4 5]
Run Code Online (Sandbox Code Playgroud)

在你的情况下,如果你有列表(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]
Run Code Online (Sandbox Code Playgroud)

您可能也对这些->->>宏感兴趣.这些宏将其参数按顺序嵌套到下一个参数中.的->宏将巢到下一表达式的第一个位置,而->>宏将巢到下一表达式的最后位置.如果"下一件事"是一个函数,两者将表现相同,并形成一个表达式(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
Run Code Online (Sandbox Code Playgroud)

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