Clojure を勉強してて、以下のような記述に出会った。
(defn add-points [& pts]
(vec (apply map + pts)))
(add-points [10 10] [-1 0])
-> [9 10]
『プログラミング Clojure 第2版』p.132
で、これについての詳しい説明は特にない。
特に説明しなくてもわかるでしょ、というところかな。
しかし、こちらは初心者だから、わからない。
どこがわからないかというと、
(apply map + ...
と、関数が3つ並んでいるのがなぜなのか、わからない。
map は + を 引数(シーケンス) のそれぞれに適用してる。
じゃ、apply はなに?
調べると、apply は、(apply f seq) とあると、関数 f を
シーケンスの各要素に適用するということみたい。
となると、ますますわからなくなってくる。
なぜ、apply と map が並んでいるの?
結論からいうと、引数pts についての理解不足だった。
(def print-pts [& pts]
(println pts))
としてみるとよくわかる。
(print-pts [10 10] [-1 0])
-> ([10 10] [-1 5])
というように、[10 10] と [-1 0] からなるシーケンスなのだった。
だから、
(apply map + pts)
は
(apply map + '([10 10] [-1 0]))
あるいは
(apply map + [[10 10] [-1 0]])
ということになる。
で、(9 10) という結果が返ってくるから、
(vec '(9 10))
-> [9 10]
と ベクタに変換している。
このことがわかるのに、2日かかった。
もちろん、仕事したり他のことしながらだけど。
教室などで教わっていると、こういうのは先生が一発で教えてくれるだろう。
このあたりが、独学の難しさであるが、こういう廻り道が楽しかったりするのである。
参考
『プログラミング Clojure 第2版』
Stuart Halloway / Aaron Bedra 著
川合史朗 訳
オーム社
平成25年 4月 25日 第2版第1刷