Clojure -- what is the correct way to apply functions in sequence to an argument?
I'm not clear on the difference between ->
and ->>
in Clojure: from the API reference, it seems like the latter would be the correct way to apply several functions in sequence, i.e. (->> x h g f) would result in f(g(h(x))).
This is related to how Lisp-like language differentiate f(x, y) and (f(x))(y), whereas Haskell does not, correct? (Using math notation; commas intended to imply n-ary functions, not tupling).
Thanks in advance!
Edit
I'm wrong, neither work except on simple functions like (def inc #(+ 1 %)), where they both work.
Here's an example of a function that doesn't work with ->
or ->>
,
(defn mkinc [amnt] (fn [x] (+ x amnt)))
(-> 3 (mkinc 2))
; ERROR -- Wrong number of args (2) passed to: sandbox58780$fn--58797$mkinc
((mkinc 2) 开发者_开发百科3)
; 5
->
and ->>
are equivalent if all the functions take only one argument. Otherwise, ->
passes the value being threaded as the first argument to the function where as ->>
passes it as the last argument. The following example should make this clear:
(-> x
(f 1 2)
(g 3 4)
(h 5 6))
becomes
(h (g (f x
1 2)
3 4)
5 6)
or h(g(f(x, 1, 2), 3, 4), 5, 6)
(->> x
(f 1 2)
(g 3 4)
(h 5 6))
becomes
(h 5 6
(g 3 4
(f 1 2 x)))
or h(5, 6, g(3, 4, f(1, 2, x)))
Edit: (Responding to the Edit in the question, copying this from the comments).
The example doesn't work because the ->
macro inserts the 3 as the first arg of mkinc
.
See (macroexpand-1 '(-> 3 (mkinc 2)))
to understand this better.
This does work: (-> 3 ((mkinc 2)))
.
See (macroexpand-1 '(-> 3 ((mkinc 2))))
to understand why.
-> inserts the prev form into the 2nd position. Whereas ->> inserts into the last position. Taking a page from Joy of Clojure, note the insertion point marked by ,,,
(-> x (f ,,, 1) (g ,,, 2) (h ,,, 3))
(->> x (f 1 ,,,) (g 2 ,,,) (h 3 ,,,))
In case there's no solution, I managed to hack it with syntax macros,
(defmacro fwcomp [& fcns] `(comp ~@(reverse fcns)))
(defmacro |> [x & fcns] `((fwcomp ~@fcns) ~x))
Usage:
(|> x h g f) ; equal to f(g(h(x)))
精彩评论