Last active
May 8, 2018 16:01
-
-
Save danielneal/eb192747852a5465c0a06da5db29af17 to your computer and use it in GitHub Desktop.
Thinking about compound some more
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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