clojure线程操作符

clojure线程操作符,clojure,Clojure,假设我想使用threading操作符通过一系列函数调用对映射执行线程。所有函数都将map作为第一个参数(好),但有一个函数不符合正确的签名(假设它将map作为最后一个参数)。“修复”函数签名的最佳方法是什么?用于匿名函数的reader宏#()是一个很好的选择: (-> your-arg (fn1 arg2 arg3) (fn2 arg4 arg5) (#(fn3 arg6 arg7 %)) ) 它是灵活的,增加了很少的视觉噪音。当然,您可以做许多不同的事情,在这种情况下,部分

假设我想使用threading操作符通过一系列函数调用对映射执行线程。所有函数都将map作为第一个参数(好),但有一个函数不符合正确的签名(假设它将map作为最后一个参数)。“修复”函数签名的最佳方法是什么?

用于匿名函数的reader宏
#()
是一个很好的选择:

(-> your-arg
  (fn1 arg2 arg3)
  (fn2 arg4 arg5)
  (#(fn3 arg6 arg7 %)) )
它是灵活的,增加了很少的视觉噪音。当然,您可以做许多不同的事情,在这种情况下,部分函数应用程序也可以工作:

(-> your-arg
  (fn1 arg2 arg3)
  ((partial fn2 arg4 arg5)))
还有一个
->
宏,它将第一个表达式线程化到最后一个位置。当然,在您的用例中,这没有多大帮助,因为您必须调整一些函数调用。但是,如果要链接多个函数,这些函数应将表达式作为第一个参数,然后链接多个函数,这些函数应将表达式作为最后一个参数,则可以执行以下操作

(->>
  (-> your-arg
    (fn1 arg2 arg3)
    (fn2 arg5 arg6))
  (fn3 arg7 arg8)
  (fn4 arg10 arg11))
编辑:在第一个示例中添加了额外的括号

(-> your-arg
    (fn1 arg2 arg3)
    (fn2 arg5 arg6)
    (->> (fn3 arg7 arg8)
         (fn4 arg10 arg11)))

对我来说,似乎比在“
->
”之前加上“
->
”的版本更好。您可以做的另一件事是编写一些基本的参数重新排序函数,并使用这些函数来创建
fn3
fn4
的版本,这些版本按照您想要的顺序获取参数。

我认为人们往往低估了clojure中可用的线程操作符类型。让我向您介绍as->线程操作符

as->thread创建一个变量,该变量接受线程步骤中每个函数调用的值。例如

(as-> 2 x        ;; x = 2
      (+ 3 x)    ;; x = 5
      (- x 1)    ;; x = 4
      (/ x 2)    ;; x = 2
      (+ x x x)) ;; x = 6

上述操作的输出为x,即6。

但这是否确实有效?因为#()返回的函数不是->所期望的。@Kevin,你只需要额外的括号
(>[1 2 3 4](conj 5)(#(map inc%))
我觉得我最喜欢部分解,尽管我觉得额外的括号很难看(也许我只是太挑剔了)。谢谢我也喜欢partial(它感觉很实用;),但是#()更通用(我想象你有一个函数,你想在其中插入一些东西作为中间参数(这会发生吗?)。