可以clojure评估一个混合的arity函数链,如果需要返回一个部分函数? [英] Can clojure evaluate a chain of mixed arity functions and return a partial function if needed?

查看:232
本文介绍了可以clojure评估一个混合的arity函数链,如果需要返回一个部分函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有三个函数的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆