Clojure:实现comp函数 [英] Clojure: Implementing the comp function
问题描述
4Clojure 问题58 表示为:
4Clojure Problem 58 is stated as:
编写一个函数,使您可以创建函数组合。参数列表应包含可变数量的函数,并创建一个从右到左应用它们的函数。
Write a function which allows you to create function compositions. The parameter list should take a variable number of functions, and create a function applies them from right-to-left.
(= [3 2 1] ((__ rest reverse) [1 2 3 4]))
(= 5 ((__ (partial + 3) second) [1 2 3 4]))
(= true ((__ zero? #(mod % 8) +) 3 5 7 9))
(= "HELLO" ((__ #(.toUpperCase %) #(apply str %) take) 5 "hello world"))
此处 __
应替换为解决方案。
Here __
should be replaced by the solution.
在此问题中,函数 comp
我找到的解决方案是:
(fn [& xs]
(fn [& ys]
(reduce #(%2 %1)
(apply (last xs) ys) (rest (reverse xs)))))
它有效。但我不太了解 reduce
在这里的工作方式。
It works. But I don't really understand how the reduce
works here. How does it represent (apply f_1 (apply f_2 ...(apply f_n-1 (apply f_n args))...)
?
推荐答案
让我们尝试在3个阶段中修改该解决方案。每个解决方案都待一会儿,看看是否能获得解决方案。停止这样做的时间和时间,以免令我更加困惑
Let's try modifying that solution in 3 stages. Stay with each for a while and see if you get it. Stop if and when you do lest I confuse you more.
首先,让我们使用更具描述性的名称
First, let's have more descriptive names
(defn my-comp [& fns]
(fn [& args]
(reduce (fn [result-so-far next-fn] (next-fn result-so-far))
(apply (last fns) args) (rest (reverse fns)))))
(defn my-comp [& fns]
(fn [& args]
(let [ordered-fns (reverse fns)
first-result (apply (first ordered-fns) args)
remaining-fns (rest ordered-fns)]
(reduce
(fn [result-so-far next-fn] (next-fn result-so-far))
first-result
remaining-fns))))
next replace reduce用一个相同的循环
next replace reduce with a loop which does the same
(defn my-comp [& fns]
(fn [& args]
(let [ordered-fns (reverse fns)
first-result (apply (first ordered-fns) args)]
(loop [result-so-far first-result, remaining-fns (rest ordered-fns)]
(if (empty? remaining-fns)
result-so-far
(let [next-fn (first remaining-fns)]
(recur (next-fn result-so-far), (rest remaining-fns))))))))
这篇关于Clojure:实现comp函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!