【发布时间】:2010-12-13 23:50:14
【问题描述】:
我正在寻找一种干净、惯用的方式来在 Clojure 中进行“向后减少”。
我有
(def fns '(fn1 fn2 fn3))
(def val 42)
我想获得(fn3 (fn2 (fn1 val))),我对订单并不挑剔。所以我想将一系列函数连续应用于一个值,而不是连续将一系列值应用于一个函数。
建议?谢谢!
【问题讨论】:
标签: map clojure functional-programming
我正在寻找一种干净、惯用的方式来在 Clojure 中进行“向后减少”。
我有
(def fns '(fn1 fn2 fn3))
(def val 42)
我想获得(fn3 (fn2 (fn1 val))),我对订单并不挑剔。所以我想将一系列函数连续应用于一个值,而不是连续将一系列值应用于一个函数。
建议?谢谢!
【问题讨论】:
标签: map clojure functional-programming
在 Clojure 中写下它的最简单方法是:
((comp fn3 fn2 fn1) 42)
【讨论】:
另一种思考方式是将其视为函数的组合:
user=> ((apply comp [inc dec inc]) 42)
43
【讨论】:
((comp f1 f2 f3) x) 的计算结果为 (f1 (f2 (f3 x))),而提问者则希望反过来。
这只是减少。记住函数也是对象。此外,您仍在按 f1、f2 等顺序应用您的功能。 不要与它读取的事实混淆 (f4 (f3 ...
所以只需使用常规 reduce。
(reduce #(%2 %1) val functions)
【讨论】:
(list fn1 fn2 fn3) 或[fn1 fn2 fn3];向量版本在 Clojure 中更惯用。
怎么样...
(defn back-reduce
([firstfunction restfunctions val]
(if (= restfunctions nil)
(firstfunction val)
(back-reduce (car restfunctions) (cdr restfunctions) (firstfunction val))
)
))
【讨论】:
我也不是一个非常高级的 Clojure 用户,所以 API 描述的语言对我来说往往看起来有点简洁和神秘。但鉴于我的理解有限,“->”宏引起了我的注意。它通过一系列“形式”“串接”一个值 x,这在我看来与您所追求的相似。
由于它是一个宏,我不确定您是否可以使用(应用)将其推送到您的 fn 列表中,但我会试一试!
【讨论】: