-
-
Save michaelklishin/035d79153dd3781fd179 to your computer and use it in GitHub Desktop.
This file contains 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
(defn fpartial | |
"Like clojure.core/partial but prepopulates last N arguments (first is passed in later)" | |
[f & args] | |
(fn [arg & more] (apply f arg (concat args more)))) | |
(defprotocol IFNExpansion | |
(expand-all [x] "Replaces functions with their invocation results, recursively expands maps, evaluates all other values to themselves") | |
(expand-all-with [x f] "Replaces functions with their invocation results that function f is applied to, recursively expands maps, evaluates all other values to themselves")) | |
(extend-protocol IFNExpansion | |
java.lang.Integer | |
(expand-all [i] i) | |
(expand-all-with [i f] i) | |
java.lang.Long | |
(expand-all [l] l) | |
(expand-all-with [l f] l) | |
java.lang.String | |
(expand-all [s] s) | |
(expand-all-with [s f] s) | |
java.lang.Float | |
(expand-all [fl] fl) | |
(expand-all-with [fl f] fl) | |
java.lang.Double | |
(expand-all [d] d) | |
(expand-all-with [d f] d) | |
;; exact map implementation classes are necessary because maps are also functions, | |
;; and this comes to bite us here. MK. | |
clojure.lang.PersistentHashMap | |
(expand-all [m] (apply-to-values m expand-all)) | |
(expand-all-with [m f] (apply-to-values m (fpartial expand-all-with f))) | |
clojure.lang.PersistentArrayMap | |
(expand-all [m] (apply-to-values m expand-all)) | |
(expand-all-with [m f] (apply-to-values m (fpartial expand-all-with f))) | |
clojure.lang.PersistentTreeMap | |
(expand-all [m] (apply-to-values m expand-all)) | |
(expand-all-with [m f] (apply-to-values m (fpartial expand-all-with f))) | |
clojure.lang.IPersistentVector | |
(expand-all [v] (map expand-all v)) | |
(expand-all-with [v f] (map (fpartial expand-all-with f) v)) | |
clojure.lang.IFn | |
(expand-all [f] (f)) | |
(expand-all-with [f expander] (do | |
(println f) | |
(expander (f)))) | |
Object | |
(expand-all [x] x) | |
(expand-all-with [x f] x)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment