In clojure, how does one thrush through a list of functions?
在Clojure中,我想通过一个函数列表来推送一个画眉值,但是我不确定如何以惯用的方式这样做。我的想法是,我将拥有一个包含未知数量功能的列表,并且我想利用鹅口疮的各种特性。
所以,这样的事情...
1 2 3 4 5 | (->> 1 inc inc inc) ; 4 (->> 1 '(inc inc inc)) ; does not work, of course |
reduce在这种情况下可以很好地做到这一点
1 2 3 4 5 6 | user> (reduce #(%2 %1) 1 [inc inc inc]) 4 user> (defn thrush [val funs] (reduce #(%2 %1) val funs)) #'user/thrush user> (thrush 1 [inc inc inc dec]) 3 |
在可能的情况下,可以通过宏对此类函数进行功能
我认为
1 2 | => ((comp inc inc inc) 1) 4 |
如果函数通常使用可变参数,但您希望将其作为集合,则将其与惯用的
1 2 | => ((apply comp (repeat 3 inc)) 1) 4 |
请注意,尽管它从右向左滚动
1 2 3 4 | => ((comp str inc inc inc) 1) "4" => ((comp inc inc inc str ) 1) ClassCastException java.lang.String cannot be cast to java.lang.Number |
这也更符合Clojure / Lisp s表达式。
如果您想要更"容易"理解的符号,那么Arthur Ulfeldt的答案是完全可以接受的,并且是简化和功能编程的一个很好的例子。不过,按原样使用它可能会妨碍您熟悉s表达式的"简单性"。.
请注意宏的!
->和->>是宏的原因是它们积极地重写形式,因此您可以在范围内使用通常不完整的参数表示法,例如
在转向宏之前,最好学会充分利用正常功能。对于不习惯的人来说,有很多陷阱,应该谨慎使用。
怎么样:
1 2 3 4 | user=> (def my-fns [inc inc inc]) #'user/my-fns user=> (->> 1 ((apply comp my-fns))) 4 |
我想你可以这样做:
1 2 3 | (defmacro thrush-list [x flist] `(->> ~x ~@flist)) (thrush-list 1 [inc inc inc]) ; 4 |