(defn ^:skip-wiki merge-spec-impl
"Do not call this directly, use 'merge'"
[forms preds gfn]
(reify
Specize
(specize* [s] s)
(specize* [s _] s)
Spec
(conform* [_ x] (let [ms (map #(dt %1 x %2) preds forms)]
(if (some invalid? ms)
::invalid
(apply c/merge ms))))
(unform* [_ x] (apply c/merge (map #(unform % x) (reverse preds))))
(explain* [_ path via in x]
(apply concat
(map #(explain-1 %1 %2 path via in x)
forms preds)))
(gen* [_ overrides path rmap]
(if gfn
(gfn)
(gen/fmap
#(apply c/merge %)
(apply gen/tuple (map #(gensub %1 overrides path rmap %2)
preds forms)))))
(with-gen* [_ gfn] (merge-spec-impl forms preds gfn))
(describe* [_] `(merge ~@forms))))