可以clojure评估一个混合的arity函数链,如果需要返回一个部分函数? [英] Can clojure evaluate a chain of mixed arity functions and return a partial function if needed?
问题描述
假设您有三个函数的arity 1,2和3如下:
(defn I [x] x)
(defn K [xy] x)
(defn S [xyz](xz(yz)))
clojure是否具有评估函数或习语用于评估:
(IKSII)as返回arity 2的一个parital函数? / p>
我考虑创建一个宏,它可以接受上面的简单函数定义,并将它们展开为可返回部分结果的多元函数。我不想创建宏,如果已经有一个内置的或惯用的方法来完成这一点。
这里是扩展的宏将喜欢上述功能:
(defn I
([x] I x)
([x& more] apply(I x)more)))
(defn K
([x](partial K x))
([xy] x)
xy>([xy](partial(x,y))(更多)(apply(K xy)more)))
(defn S
S xy))
([xyz](xz(yz)))
([xyz& more](apply(S xyz)more)))
解决方案我不确定我是否完全理解你想要做什么, http://clojuredocs.org/clojure_core/clojure.core/comp> 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]
在您的情况下,如果您有 (IKSII)
,并且您想要将其评估为(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]
您也可能对 - >
或 - >>
宏。这些宏将它们的参数按顺序嵌套到下一个参数中。 - >
宏将嵌套到下一个表达式的第一个位置,而 - >>
宏将嵌套到下一个表达式的最后一个位置。如果next thing是一个函数,两者的行为都是一样的,并且形成一个(函数嵌套 - 事物到目前为止)
的表达式,然后继续。 / p>
真的,例子最好:
( - > 1 + 10)( - 100)inc)
; //扩展到...
(inc( - (+ 1 10)100))
; //在REPL中求值。
user> ( - > 1(+ 10)( - 100)inc)
=> -88
( - >> 1(+ 10)( - 100)inc)
; //扩展到...
10 1)))
; //在REPL ...中评估...
user> ( - > 1(+ 10)( - 100)inc)
=> 90
但是,看起来更像是想做一些涉及自动currying我不认为我完全理解),因为我不知道任何预先存在的内置方式。
Suppose you have three functions of arity 1, 2 and 3 as below:
(defn I [x] x)
(defn K [x y] x)
(defn S [x y z] (x z (y z)))
Does clojure have an evaluation function or idiom for evaluating:
(I K S I I) as (I (K (S (I (I)))))
returning a parital function of arity 2?
I am considering creating a macro that can take the simple function definitions above and expand them to multi-arity functions that can return partial results. I would not want to create the macro if there is already a built in or idiomatic way to accomplish this.
Here is what the expanded macros would like for the above functions:
(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)))
解决方案 I'm not sure I fully understand what you are trying to do, but the comp
function is useful for doing this kind of "function chaining" you seem to be talking about. For example:
user> ((comp vec rest list) 1 2 3 4 5)
=> [2 3 4 5]
Which is equivalent to:
user> (vec (rest (list 1 2 3 4 5)))
=> [2 3 4 5]
In your case, if you have the list (I K S I I)
, and you want to evaluate it as (I (K (S (I (I)))))
, I would use (reduce comp ...)
, but you could also use (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]
You may also be interested in the ->
or ->>
macros. These macros nest their arguments sequentially into the next arguments. The ->
macro will nest into the first position of the next expression, whereas the ->>
macro will nest into the last position of the next expression. If the "next thing" is a function, both will behave the same, and form an expression of (function nested-things-so-far)
, and continue along.
Really, examples are best:
(-> 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
However, it seems more like you want to do something involving auto-currying (although, again, I don't think I fully understand), and for that I don't know of anything pre-existing built-in way.
这篇关于可以clojure评估一个混合的arity函数链,如果需要返回一个部分函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!