4clojure #58 Function Composition

4clojure #58 Function Composition

関数を組み立てる関数を求める。 パラメーターリストは複数の関数で、求める関数は、それらを右から左にapplyさせます。 ※ compは使用禁止。

(= [3 2 1] ((__ rest reverse) [1 2 3 4]))
(= 5 ((__ (partial + 3) second) [1 2 3 4]))
(= true ((__ zero? #(mod % 8) +) 3 5 7 9))
(= "HELLO" ((__ #(.toUpperCase %) #(apply str %) take) 5 "hello world"))

考え方

引数 & args の関数(1)を返す、引数 & funcs の関数(2)を作る。 ほとんどの処理は(1)のなかでおこなう。 reverse funcs に対して、 args をapplyする。 apply した結果を次の関数への入力にしてという繰り返しなので、 reduce を使う。 答えは seq でなく、listの要素なので、 apply した結果はlistに格納して、答えとしてはその要素を取り出す。

(((fn comb [& funcs]
  (fn [& args]
    (first
      (reduce #(list (apply %2 %1)) args (reverse funcs)))))
        #(.toUpperCase %) #(apply str %) take) 5 "hello world"))
参考答え
(fn comb [& funcs]
  (fn [& args]
    (first
      (reduce #(vector (apply %2 %1)) args (reverse funcs)))))