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)
我不确定我完全理解你想要做什么,但是这个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)
然而,似乎更像是你想要做一些涉及自动调整的事情(虽然,我认为我并不完全理解),为此我不知道任何预先存在的内置方式.