2013年2月7日木曜日

Destructuringを使おう

Clojureで積極的にDestructuringを使っていこうという話です。

ListやVectorに対する再帰


例: index-of

(defn index-of [value coll]
(loop [index 0 coll coll]
(cond (empty? coll) nil
(= value (first coll)) index
:else (recur (inc index) (rest coll)))))
view raw index_of1.clj hosted with ❤ by GitHub

Destructuringを使うとこんな感じで書ける。

(defn index-of' [value coll]
(loop [index 0 [head & tail :as coll] coll]
(cond (empty? coll) nil
(= value head) index
:else (recur (inc index) tail))))
view raw index_of2.clj hosted with ❤ by GitHub

firstとrestがなくなりました。

例: end

(defn end [coll]
(if (empty? (rest coll))
(first coll)
(recur (rest coll))))
view raw end1.clj hosted with ❤ by GitHub

Destructuringは関数の引数部に直接書ける。

(defn end' [[head & tail]]
(if (empty? tail)
head
(recur tail)))
view raw end2.clj hosted with ❤ by GitHub

リスト全体を束縛する変数を省略出来ました。

MapやRecordに対するDestructuring


レコードに対する操作

(defrecord Complex [real imaginary])
view raw complex.clj hosted with ❤ by GitHub

例: abs

(defn abs [complex]
(Math/sqrt (+ (Math/pow (:real complex) 2)
(Math/pow (:imaginary complex) 2))))
view raw abs1.clj hosted with ❤ by GitHub

Destructuringを使うとこんな感じ。

(defn abs' [{:keys [real imaginary]}]
(Math/sqrt (+ (Math/pow real 2)
(Math/pow imaginary 2))))
view raw abs2.clj hosted with ❤ by GitHub

{:keys [foo bar ...]}はフィールドを列挙することでその値を束縛します。

例: add

(defn add [complex complex']
(assoc complex
:real (+ (:real complex) (:real complex'))
:imaginary (+ (:imaginary complex) (:imaginary complex'))))
view raw add1.clj hosted with ❤ by GitHub

フィールドと違った名前の変数名を付ける場合は{foo' :foo bar' :bar ...}という記法が使えます。

(defn add' [{:keys [real imaginary] :as complex}
{real' :real imaginary' :imaginary}]
(assoc complex
:real (+ real real')
:imaginary (+ imaginary imaginary')))
view raw add2.clj hosted with ❤ by GitHub

Destructuringを使うことで要素の取得、束縛を簡素にしませんか?

0 件のコメント:

コメントを投稿