我正在研究这个公案的解决方案.我很困惑为什么我的解决方案不起作用,但使用定义comp确实有效.当我看到comp的定义时,我看到:
(defn comp
"Takes a set of functions and returns a fn that is the composition
of those fns. The returned fn takes a variable number of args,
applies the rightmost of fns to the args, the next
fn (right-to-left) to the result, etc."
{:added "1.0"}
([f] f)
([f g]
(fn
([] (f (g)))
([x] (f (g x)))
([x y] (f (g x y)))
([x y z] (f (g x y z)))
([x y z & args] (f (apply g x y z args)))))
([f g h]
(fn
([] (f (g (h))))
([x] (f (g (h x))))
([x y] (f (g (h x y))))
([x y z] (f (g (h x y z))))
([x y z & args] (f (g (apply h x y z args))))))
([f1 f2 f3 & fs]
(let [fs (reverse (list* f1 f2 f3 fs))]
(fn [& args]
(loop [ret (apply (first fs) args) fs (next fs)]
(if fs
(recur ((first fs) ret) (next fs))
ret))))))
Run Code Online (Sandbox Code Playgroud)
而我的解决方案非常相似:
(defn mycomp
([f] f)
([f1 f2]
(fn
([] (f1 (f2)))
([a] (f1 (f2 a)))
([a & more] (f1 (apply f2 a more)))
)
)
([f1 f2 & fs]
(let [fxns (reverse (list f1 f2 fs))]
(fn [& args]
(loop [ret (apply (first fxns) args) fxns (next fxns)]
(if fxns
(recur ((first fxns) ret) (next fxns))
ret))))))
Run Code Online (Sandbox Code Playgroud)
根据我的判断,两者之间的最大区别在于第一个定义包含三个或更多个函数,而第二个定义包含两个或更多个函数.
请指出我的定义有什么不对.
(list f1 f2 fs)看起来很可能 - 前两个是函数,最后一个是函数列表,所以你要创建一个包含多个对象类型的列表,然后统一处理它们.您可以通过使用list*来修复它.
但作为一个更广泛的观点:圣洁的jeez,不要尝试做"两个或更多"的功能,只做零或更多!没有特殊情况意味着更少的代码; clojure.core只有一堆展开的速度案例.如果你的骨骼是(fn [& fs] (fn [& args] ...)),你的生活会更容易.
| 归档时间: |
|
| 查看次数: |
181 次 |
| 最近记录: |