在clojure中,如何通过一系列函数?

ryb*_*ome 2 clojure

在clojure中,我想通过函数列表推送画眉值,但我不确定如何以惯用的方式这样做.我的想法是,我将有一个包含未知数量函数的列表,我想利用鹅口疮的可变性质.

所以,像这样......

(->> 1 inc inc inc)
; 4

(->> 1 '(inc inc inc))
; does not work, of course
Run Code Online (Sandbox Code Playgroud)

Art*_*ldt 6

reduce在这种情况下做得很好

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
Run Code Online (Sandbox Code Playgroud)

在可能的情况下,可以通过宏来实现这些功能


Nie*_*lsK 5

我认为这comp是最惯用的选项,尽管它会有前缀语法.这也更符合正常的Clojure(fn args)表示法.

=> ((comp inc inc inc) 1)
4
Run Code Online (Sandbox Code Playgroud)

apply如果一个函数通常采用可变参数,但是你希望将它作为一个集合提供,那么将它与惯用语结合起来.

=> ((apply comp (repeat 3 inc)) 1)
4
Run Code Online (Sandbox Code Playgroud)

请注意,虽然它从右到左穿线

=> ((comp str inc inc inc) 1)
"4"
=> ((comp inc inc inc str ) 1)
ClassCastException java.lang.String cannot be cast to java.lang.Number
Run Code Online (Sandbox Code Playgroud)

这也更符合Clojure/Lisp s表达式.

如果你想要更"简单"的人类可读符号,Arthur Ulfeldt的答案是完全可以接受的,并且是减少和函数式编程的一个很好的例子."按原样"使用它可能会妨碍熟悉s表达式的"简单性".

小心宏!

之所以 - >和 - >>是宏的原因是它们主动重写表单,所以你可以(filter odd?)在其范围内使用通常不完整的参数表示法,而不必过度使用partial.这不能通过正常的功能组合来完成.

在转向宏之前,最好学会充分利用正常的功能构成.对于不习惯的人来说,有很多陷阱,应该谨慎使用.