updateやupdate-inが便利すぎてついつい使いすぎてしまう。
気づくと「もっとストレートな書き方があるのに…」というパターン(update+assocとかupdate-in+updateとか)を書いていたりするのでちょっと整理してみた。
前提
get/assoc/updateの性質
(get (assoc m k v) k)=v(assoc m k (get m k))=m(update m k f x ...)=(assoc m k (f (get m k) x ...))
get-in/assoc-in/update-inの形式的定義
get-in
(get-in m [k])=(get m k)(get-in m [k ks ...])=(get (get-in m [ks ...]) k)
assoc-in
(assoc-in m [k] v)=(assoc m k v)(assoc-in m [k ks ...] v)=(assoc m k (assoc-in (get m k) ks v))
update-in
(update-in m [k] f x ...)=(update m k f x ...)(update-in m [k ks ...] f x ...)=(update m k update-in [ks ...] f x ...)
get-in/assoc-in/update-inの書き換え
以上のget/assoc/updateの性質とget-in/assoc-in/update-inの定義から、次が導出できる(はず)。
単純な書き換え
(get-in (get m k) [ks ...])=(get-in m [k ks ...])(get-in (get-in m [ks1 ...]) [ks2 ...])=(get-in m [ks1 ... ks2 ...])(assoc-in m [ks ...] (assoc (get-in m [ks ...]) k v))=(assoc-in m [ks ... k] v)- 特に、
(empty? (get-in m [ks ...]))の場合、(assoc-in m [ks ...] (assoc {} k v))=(assoc-in m [ks ... k] v)
- 特に、
(assoc-in m [ks1 ...] (assoc-in (get-in m [ks1 ...]) [ks2 ...] v))=(assoc-in m [ks1 ... ks2 ...] v)- 特に、
(empty? (get-in m [ks1 ...]))の場合、(assoc-in m [ks1 ...] (assoc-in {} [ks2 ...] v))=(assoc-in m [ks1 ... ks2 ...] v)
- 特に、
(update-in m [ks ...] update k f x ...)=(update-in m [ks ... k] f x ...)(update-in m [ks1 ...] update-in [ks2 ...] f x ...)=(update-in [ks1 ... ks2 ...] f x ...)
より複雑な書き換え
(assoc m k1 (update (get m k1) k2 f x ...))=(update-in m [k1 k2] f ...)- 特に、
(empty? (get m k1))の場合、(assoc m k1 (update {} k2 f x ...))=(update-in m [k1 k2] f ...)
- 特に、
(assoc-in m [ks1 ...] (update-in (get-in m [ks1 ...]) [ks2 ...] f x ...))=(update-in m [ks1 ... ks2 ...] f x ...)- 特に、
(empty? (get-in m [ks1 ...]))の場合、(assoc-in m [ks1 ...] (update-in {} [ks2 ...] f x ...))=(update-in m [ks1 ... ks2 ...] f x ...)
- 特に、
(update m k1 assoc k2 v)=(assoc-in m [k1 k2] v)(update-in m [ks1 ...] assoc-in [ks2 ...] v)=(assoc-in m [ks1 ... ks2 ...] v)
証明
読者への課題とする。□