永続的なデータ構造は実装に関するものであり、「基礎となる構造を見る」ことではありません。Joostが言ったように(+1)、「diff」を使用できます。「{:keys ... :value ...}」パターンを使用して回答を変換するだけです。
(def p1 {:a {:a1 :1 :a2 :2}
:b {:b1 :1 :b2 {:b11 :11 :b22 :22}}})
(def p2 {:a {:a1 :updated1 :a2 :2}
:b {:b1 :1 :b2 {:b11 :updated2 :b22 :updated3}}})
(defn what-changed?* [m]
(if (not (map? m))
[(list m)]
(apply concat (map (fn [k]
(map (fn [nest-k]
(conj nest-k k))
(nested-keys (m k))))
(keys m)))))
(defn what-changed? [m1 m2]
(map (fn [l] {:keys (drop-last l) :value (last l)})
(nested-keys (second (data/diff m1 m2)))))
テスト:
(what-changed? p1 p2)
-> ({:keys (:a :a1), :value :updated1}
{:keys (:b :b2 :b11), :value :updated2}
{:keys (:b :b2 :b22), :value :updated3})
(what-changed? p2 p1)
-> ({:keys (:a :a1), :value :1}
{:keys (:b :b2 :b11), :value :11}
{:keys (:b :b2 :b22), :value :22})
ところで、「update-in」の代わりに「assoc-in」でハッシュマップを変更できます。
(assoc-in {:a {:a1 :1 :a2 :2}
:b {:b1 :1 :b2 :2}}
[:a :a1] :updated)
-> {:a {:a2 :2, :a1 :updated}
:b {:b2 :2, :b1 :1}}