Clojure - 将函数按顺序应用于参数的正确方法是什么?

时间:2011-06-16 02:04:41

标签: clojure

我不清楚Clojure中->->>之间的区别:从API reference来看,后者似乎是顺序应用多个函数的正确方法,即( - >> xhgf)会产生 f(g(h(x)))

这与Lisp类语言如何区分 f(x,y)(f(x))(y)有关,而Haskell则没有,正确? (使用数学符号;逗号旨在暗示n-ary函数,而不是tupling)。

提前致谢!

修改

我错了,除了像(def inc#(+ 1%))这样的简单函数之外,它们都没有工作。

以下是与->->>不兼容的功能示例,

(defn mkinc­ [amnt­] (fn [x] (+ x amnt)­))
(-> 3 (mkin­c 2))
; ERROR -- Wrong number of args (2) passed to: sandbox58780$fn--58797$mkinc
((mkinc 2) 3)
; 5

3 个答案:

答案 0 :(得分:21)

如果所有函数只接受一个参数,则

->->>是等效的。否则,->将作为第一个参数的线程传递给函数,其中->>将其作为 last 参数传递给它。以下示例应明确说明:

(-> x
    (f 1 2)
    (g 3 4)
    (h 5 6))

变为

(h (g (f x
         1 2)
      3 4)
   5 6)

h(g(f(x, 1, 2), 3, 4), 5, 6)

(->> x
     (f 1 2)
     (g 3 4)
     (h 5 6))

变为

(h 5 6
   (g 3 4
      (f 1 2 x)))

h(5, 6, g(3, 4, f(1, 2, x)))

修改 :(回答问题中的编辑,将其从评论中复制出来)。

该示例不起作用,因为->宏将3插入mkinc的第一个arg。 请参阅(macroexpand-1 '(-> 3 (mkinc 2)))以更好地理解这一点。

这确实有效:(-> 3 ((mkinc 2)))。 请参阅(macroexpand-1 '(-> 3 ((mkinc 2))))以了解原因。

答案 1 :(得分:3)

- >将prev形式插入第二个位置。然而 - >>插入最后一个位置。从Joy of Clojure中获取页面,请注意标有,,,

的插入点
(-> x (f ,,, 1) (g ,,, 2) (h ,,, 3))

(->> x (f 1 ,,,) (g 2 ,,,) (h 3 ,,,))

答案 2 :(得分:1)

如果没有解决方案,我设法用语法宏

破解它
(defmacro fwcomp [& fcns] `(comp ~@(reverse fcns)))
(defmacro |> [x & fcns] `((fwcomp ~@fcns) ~x))

用法:

(|> x h g f) ; equal to f(g(h(x)))