   ([fs m]
    (cond
      ;; map the fn for sequential/set types
-     (list? fs) (lst-fapply fs m)
-     (seq? fs) (seq-fapply fs m)
-     (vector? fs) (vec-fapply fs m)
-     (set? fs) (set-fapply fs m)
+     (list? fs) (with-meta (lst-fapply fs m) (meta m))
+     (seq? fs) (with-meta (seq-fapply fs m) (meta m))
+     (vector? fs) (with-meta (vec-fapply fs m) (meta m))
+     (set? fs) (with-meta (set-fapply fs m) (meta m))
      ;; match keys for maps and if found apply the fn (otherwise
      ;;  just leave it)
-     (map? fs) (assc-fapply fs m)
+     (map? fs) (with-meta (assc-fapply fs m) (meta m))
      ;; base cases:
      ;; either use the fn
      (fn? fs) (fs m)

   (repeat x))
  ([fs x]
   (cond
     (vector? fs) (vec-zip fs x)
     (seq? fs) (reverse (vec-zip fs x))
     (map? fs) (map-zip fs x)))
  ([fs x y]
   (cond
     (vector? fs) (vec-zip fs x [y])
     (seq? fs) (reverse (vec-zip fs x [y]))
     (map? fs) (map-zip fs x y)))
  ([fs x y & args]
   (let [more-args (cons y args)]
     (cond
       (vector? fs) (vec-zip fs x more-args)
       (seq? fs) (reverse (vec-zip fs x more-args))
       (map? fs) (apply (partial map-zip fs x y) args)))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   ;; same thing here but we'll mutually walk ms
   (let [mcoll (cons m ms)]
     (cond
       (list? m) (with-meta (map (partial flst f) mcoll) (meta m))
       (vector? m) (with-meta (map (partial fvec f) mcoll) (meta m))
       (seq? m) (with-meta (map (partial fseq f) mcoll) (meta m))
       (set? m) (with-meta (map (partial fset f) mcoll) (meta m))
       (associative? m) (with-meta (fassc f m ms) (meta m))
       (fn? m) (map #(comp f %) mcoll)
       :else
       (apply f mcoll)))))
