clojureでは、関数のリストにツグミの値をプッシュしたいのですが、慣用的な方法でそれを行う方法がわかりません。未知数の機能を含むリストを作成するという考えで、ツグミの可変個引数の性質を利用したいと思います。
だから、このようなもの...
(->> 1 inc inc inc)
; 4
(->> 1 '(inc inc inc))
; does not work, of course
clojureでは、関数のリストにツグミの値をプッシュしたいのですが、慣用的な方法でそれを行う方法がわかりません。未知数の機能を含むリストを作成するという考えで、ツグミの可変個引数の性質を利用したいと思います。
だから、このようなもの...
(->> 1 inc inc inc)
; 4
(->> 1 '(inc inc inc))
; does not work, of course
このコンテキストでは、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
可能であれば、そのようなことのためにマクロを介して機能するように座ってください
comp
ここでは最も慣用的なオプションだと思いますが、代わりにプレフィックス構文があります。これは、通常のClojure(fn args)表記とも一致しています。
=> ((comp inc inc inc) 1)
4
apply
関数が通常可変個引数を取るが、コレクションをフィードしたい場合は、慣用句と組み合わせます。
=> ((apply comp (repeat 3 inc)) 1)
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の答えが完全に受け入れられ、reduceおよび関数型プログラミングの良い例です。それを「そのまま」使用すると、S式の「単純さ」を理解するのに邪魔になる可能性があります。
マクロに注意してください!
->と->>がマクロである理由は、フォームを積極的に書き換えるため、(filter odd?)
の使いすぎに頼ることなく、スコープのように通常は不完全な引数表記を使用できるためですpartial
。これは、通常の関数構成では実行できません。
マクロに目を向ける前に、通常の関数合成を最大限に活用することを学ぶのが最善です。慣れていない人には多くの落とし穴があり、慎重に使用する必要があります。
どうですか:
user=> (def my-fns [inc inc inc])
#'user/my-fns
user=> (->> 1 ((apply comp my-fns)))
4
私はあなたがこれを行うことができると思います:
(defmacro thrush-list [x flist] `(->> ~x ~@flist))
(thrush-list 1 [inc inc inc])
; 4