Skip to content

Instantly share code, notes, and snippets.

@KingCode
Last active October 27, 2018 10:46
Show Gist options
  • Save KingCode/a954ced2aeaa22f34332fc81f75f9969 to your computer and use it in GitHub Desktop.
Save KingCode/a954ced2aeaa22f34332fc81f75f9969 to your computer and use it in GitHub Desktop.
Scoping transducer for pipelining sub-structures without losing the container.
(require '[clojure.core.async :as async :refer [chan <!! put!]])
(defn save-to [c save-f]
(fn [rf]
(fn
([] (rf))
([acc] (rf acc))
([acc x]
(put! c (save-f x))
(rf acc x)))))
(defn restore-from [c restore-f]
(fn [rf]
(fn
([] (rf))
([acc] (rf acc))
([acc x]
(rf acc (restore-f x (<!! c)))))))
(defn scope [save putback xform]
(let [c (chan)]
(comp
(save-to c save)
xform
(restore-from c putback))))
(def m [{:a 1 :b 10} {:a 2 :b 20} {:a 3 :b 30}])
(def xt (scope #(select-keys % [:a])
#(merge % %2)
(comp (map :b)
(map inc)
(map #(conj {} [:b %])))))
(into [] xt m)
;; => [{:b 11, :a 1} {:b 21, :a 2} {:b 31, :a 3}]
(sequence xt m)
;; => ({:b 11, :a 1} {:b 21, :a 2} {:b 31, :a 3})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment