Clojure - Каков правильный способ применения функций последовательно к аргументу?

Я не понимаю разницу между -> и ->> в Clojure: из ссылка API, кажется как и последний, было бы правильным способом применить несколько функций последовательно, т.е. (- → xhgf) приведет к f (g (h (x))).

Это связано с тем, как Lisp -образный язык дифференцирует f (x, y) и (f (x)) (y), тогда как Haskell не исправляет? (Использование математической нотации, запятые, предназначенные для обозначения n-арных функций, а не чередующиеся).

Спасибо заранее!

Изменить

Я ошибаюсь, не работаю, кроме простых функций, таких как (def inС# (+ 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

Ответ 1

-> и ->> эквивалентны, если все функции принимают только один аргумент. В противном случае -> передает значение, которое передается как первый аргумент функции, где as ->> передает его в качестве последнего аргумента. Следующий пример должен сделать это ясно:

(-> 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. См. (macroexpand-1 '(-> 3 (mkinc 2))), чтобы понять это лучше.

Это работает: (-> 3 ((mkinc 2))). См. (macroexpand-1 '(-> 3 ((mkinc 2)))), чтобы понять, почему.

Ответ 2

- > вставляет предыдущую форму во вторую позицию. Принимая во внимание, что → > вставляется в последнюю позицию. Взяв страницу из Радости Clojure, отметьте точку вставки, отмеченную ,,,

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

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

Ответ 3

В случае отсутствия решения мне удалось взломать его с помощью синтаксических макросов,

(defmacro fwcomp [& fcns] `(comp [email protected](reverse fcns)))
(defmacro |> [x & fcns] `((fwcomp [email protected]) ~x))

Использование:

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