Skip to content

Instantly share code, notes, and snippets.

@gdeer81
Last active July 22, 2017 06:31
Show Gist options
  • Save gdeer81/02484a9e9f6631cea3a381bce40e1d40 to your computer and use it in GitHub Desktop.
Save gdeer81/02484a9e9f6631cea3a381bce40e1d40 to your computer and use it in GitHub Desktop.
(def inc-coll (partial map inc))
;;#'user/inc-coll
(inc-coll [4 5 6])
;;(5 6 7)
(def inc-coll-coll (partial map inc-coll))
;;#'user/inc-coll-coll
(inc-coll-coll [[1] [2]])
;;((2) (3))
(inc-coll-coll [[1] 3])
;;IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:542)
(defn inc2 [n] (cond (sequential? n) (inc-coll n) (number? n) (inc n) :else n))
;;#'user/inc2
(def inc-coll-coll (partial map inc2))
;;#'user/inc-coll-coll
(inc-coll-coll [[1] [2]])
;;((2) (3))
(inc-coll-coll [[1] [2] 3])
;;((2) (3) 4)
;;without conditionals
(defmulti inc2 class)
;;#'user/inc2
(defmethod inc2 Number [n] (inc n))
;#object[clojure.lang.MultiFn 0x155f5b43 "clojure.lang.MultiFn@155f5b43"]
(inc2 10)
;11
(defmethod inc2 clojure.lang.Sequential [c] (map inc c))
;;#object[clojure.lang.MultiFn 0x155f5b43 "clojure.lang.MultiFn@155f5b43"]
(inc2 [1])
;(2)
(inc-coll-coll [[1] [2] 3])
;((2) (3) 4)
@sundarj
Copy link

sundarj commented Jul 22, 2017

i just found out you can easily generalise it to nthly-nested seqs by using a recursive multimethod:

boot.user=> (defmulti inc' type)
WARNING: inc' already refers to: #'clojure.core/inc' in namespace: boot.user, being replaced by: #'boot.user/inc'
#'boot.user/inc'
boot.user=> (defmethod inc' Number [x] (inc x))
#object[clojure.lang.MultiFn 0x3322c938 "clojure.lang.MultiFn@3322c938"]
boot.user=> (defmethod inc' clojure.lang.Sequential [coll] (map inc' coll))
#object[clojure.lang.MultiFn 0x3322c938 "clojure.lang.MultiFn@3322c938"]
boot.user=> (inc' [1 2 3])
(2 3 4)
boot.user=> (def inc-coll-coll (partial map inc'))
#'boot.user/inc-coll-coll
boot.user=> (inc-coll-coll [[1 2 3] 4 5 [6 7 8]])
((2 3 4) 5 6 (7 8 9))
boot.user=> (inc-coll-coll [[1 2 3] 4 5 [6 7 8 [9]]])
((2 3 4) 5 6 (7 8 9 (10)))

pretty awesome if you ask me!

@schmee
Copy link

schmee commented Jul 22, 2017

You can also do this with Specter:

user=> (require '[com.rpl.specter :as s])
nil
user=> (def numbers (s/walker number?))
#'user/numbers
user=> (s/transform numbers inc [1 2 3])
[2 3 4]
user=> (s/transform numbers inc [[1 2] [3 4 5]])
[[2 3] [4 5 6]]
user=> (s/transform numbers inc [[1 2] [3 4 5] 6 [7]])
[[2 3] [4 5 6] 7 [8]]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment