this answerを書いた後、私はspec
を使用してClojure's destructuring languageを指定しようとするように促された。ハイブリッドマップをどのように指定できますか?
(require '[clojure.spec :as s])
(s/def ::binding (s/or :sym ::sym :assoc ::assoc :seq ::seq))
(s/def ::sym (s/and simple-symbol? (complement #{'&})))
シーケンシャル非構造部分は正規表現(私はここでそれを無視しています)との仕様に簡単ですが、私はで捕まってしまいました連想的な破壊。最も基本的なケースでは、キー式への結合フォームからマップです:
(s/def ::mappings (s/map-of ::binding ::s/any :conform-keys true))
しかし、Clojureのは、同様にいくつかの特殊キーが用意されています
(s/def ::as ::sym)
(s/def ::or ::mappings)
(s/def ::ident-vec (s/coll-of ident? :kind vector?))
(s/def ::keys ::ident-vec)
(s/def ::strs ::ident-vec)
(s/def ::syms ::ident-vec)
(s/def ::opts (s/keys :opt-un [::as ::or ::keys ::strs ::syms]))
どのように作成することができたマップに::assoc
仕様を作成することができます::mappings
に準拠したマップと::opts
に準拠したマップを結合しますか?私はmerge
があることを知っている:
(s/def ::assoc (s/merge ::opts ::mappings))
しかしmerge
は基本的にand
の類似体であるため、これは、動作しません。私はor
に類似したものを探していますが、マップについては探しています。
s/and
における中間ステップとして
s/conformer
を使用することができます
ありがとうございました!私はこのようなものがあったと確信していました。しかし、それはかなり醜いと思われる。私は、より洗練されたソリューションが将来追加されることを願っています。 –