identityの別名定義でmapを便利にする
Clojureのmapでこういう変換をしたくなるときがよくある。
(1 "piyo" :foo) -> ({:hoge 1} {:hoge "piyo"} {:hoge :foo})
でも、#()で無名関数の定義をしてみると、エラーが出る。
#()の中身は、関数呼び出しorマクロor特殊形式である必要があるため、(#(1))とかやると、「IFnじゃないから呼び出せない」と怒られる。
(map #({:hoge %}) [1 2 3]) -> java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentArrayMap
マップ({})は、元々IFnを継承しているが、引数の数が1個か2個とるので、上記だと「引数の数が違う」と言われてしまう。
下記のようにすれば一応いけるが、もっと簡潔にできそう。
(map (fn [x] {:hoge x}) [1 2 3]) -> ({:hoge 1} {:hoge 2} {:hoge 3})
#()を使うには、引数をそのまま返す関数identityが使える。
(map #(identity {:hoge %}) [1 2 3]) -> ({:hoge 1} {:hoge 2} {:hoge 3})
このままだと、かえって長くなっているので、ideneityの別名を定義する。
(def | identity)
すると、下記のように書ける。
(map #(|{:hoge %}) [1 2 3]) -> ({:hoge 1} {:hoge 2} {:hoge 3})
多少は簡単になったかな?しばらく使ってみよう。
でも、「|」ではない別のもっと良い記号があるかもしれない。