写完这个答案后,我受到启发,尝试使用以下方法指定Clojure 的解构语言spec
:
(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))