Skip to content

Instantly share code, notes, and snippets.

@danielneal
Last active May 8, 2018 16:01
Show Gist options
  • Save danielneal/eb192747852a5465c0a06da5db29af17 to your computer and use it in GitHub Desktop.
Save danielneal/eb192747852a5465c0a06da5db29af17 to your computer and use it in GitHub Desktop.
Thinking about compound some more
(ns compound.scratch
(:require [net.cgrand.xforms :as x]))
(defmulti plus identity)
(defmulti minus identity)
(defmulti xform identity)
(defmulti zero identity)
(defmethod plus :count-odd-a [_] (fn
([a] a)
([a b]
(+ a b))))
(defmethod minus :count-odd-a [_] (fn
([a] a)
([a b]
(- a b))))
(defmethod zero :count-odd-a [_] 0)
(defmethod xform :count-odd-a [_] (comp
(map :a)
(filter odd?)
x/count))
(defn add-items
([k items]
(add-items (zero k) k items))
([init k items]
(transduce (xform k)
(plus k)
init
items)))
(defn remove-items
([k items]
(remove-items (zero k) k items))
([init k items]
(transduce (xform k)
(minus k)
init
items)))
(-> (add-items :count-odd-a [{:a 1} {:a 2} {:a 3} {:a 4} {:a 5}])
(add-items :count-odd-a [{:a 7} {:a 9}])
(remove-items :count-odd-a [{:a 1}]))
(defmethod plus :filter-odd-a [_] conj)
(defmethod minus :filter-odd-a [_] disj)
(defmethod zero :filter-odd-a [_] #{})
(defmethod xform :filter-odd-a [_] (comp
(map :a)
(filter odd?)))
(-> (add-items :filter-odd-a [{:a 1} {:a 2} {:a 3} {:a 4} {:a 5}])
(remove-items :filter-odd-a [{:a 1}]))
(defmethod plus :index-by-a [_] merge)
(defmethod minus :index-by-a [_] (fn
([m] m)
([m [k _]]
(dissoc m k))))
(defmethod zero :index-by-a [_] {})
(defmethod xform :index-by-a [_] (map (juxt :a identity)))
(-> (add-items :index-by-a [{:a 1} {:a 2} {:a 3} {:a 4} {:a 5}])
(remove-items :index-by-a [{:a 1}]))
(defmethod plus :flatten-a [_] conj)
(defmethod minus :flatten-a [_] disj)
(defmethod xform :flatten-a [_] (mapcat :a))
(defmethod zero :flatten-a [_] #{})
(-> (add-items :flatten-a [{:a [1 2]} {:a [2 3]} {:a [3 4]} {:a [4 5]}])
(remove-items :flatten-a [{:a [3 4 5]}]))
(x/into {} (comp (x/transjuxt {:captured (x/reduce conj [])
:even (comp (filter even?)
(x/transjuxt {:captured (x/reduce conj [])
:inc (comp (map inc)
(x/transjuxt {:captured (x/reduce conj [])
:count (comp x/count
(x/transjuxt {:captured (x/reduce conj [])}))}))}))}))
(range 5))
(defn add-items [compound items]
;; pull out the structure
;; transduce back into the structure
(comp (x/multiplex {:captured (x/reduce conj [])
:even (comp (filter even?)
(x/multiplex {:captured (x/reduce conj [])
:inc (comp (map inc)
(x/multiplex {:captured (x/reduce conj [])
:count (comp x/count
(x/multiplex {:captured (x/reduce conj [])}))}))}))}))
(range 5))
(def compound
{:by-id {:xform (x/by-key :id identity)
:index (x/into {})}
:counted {:in :by-id ; what to use as the input for the index, defaults as the input to the compound
:xform (x/by-key ) ; what to use to transform the input
:index (x/reduce conj [])}}) ; how to index the transformed sequence
(sequence
(comp (x/by-key :id (x/reduce merge))
(x/into {}))
[{:id 1 :a 2} {:id 2 :a 3} {:id 3 :a 4 :c 5}])
(sequence
(comp (x/by-key :id (x/reduce (completing (fn [acc x]
(if (nil? acc) x (throw (ex-info "Duplicate key" x)))))
nil)).
(x/into {}))
[{:id 1 :a 2} {:id 2 :a 3} {:id 2 :a 4 :c 5}])
({:captured [0 1 2 3 4 5 6 7 8 9], :inc {:captured [1 2 3 4 5 6 7 8 9 10], :even {:captured [2 4 6 8 10]}}})
(map)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment