【发布时间】:2016-08-25 13:54:28
【问题描述】:
在很大程度上,我与 clojure.spec 相处得很好。但是,在处理unform 时,我遇到了一个我无法弄清楚的问题。这是 Hiccup 的一个松散规范,可以让我们动起来:
(require '[clojure.spec :as s])
(s/def ::hiccup
(s/and
vector?
(s/cat
:name keyword?
:attributes (s/? map?)
:contents (s/* ::contents))))
(s/def ::contents
(s/or
:element-seq (s/* ::hiccup)
:element ::hiccup
:text string?))
现在,在我们得意忘形之前,让我们看看它是否适用于一个小的传递案例。
(def example [:div])
(->> example
(s/conform ::hiccup))
;;=> {:name :h1}
像魅力一样工作。但是我们可以撤消我们的一致性吗?
(->> example
(s/conform ::hiccup)
(s/unform ::hiccup))
;;=> (:div)
嗯,那应该是一个向量。我错过了什么吗?让我们看看规范对此有何评论。
(->> example
(s/conform ::hiccup)
(s/unform ::hiccup)
(s/explain ::hiccup))
;; val: (:div) fails spec: :user/hiccup predicate: vector?
;;=> nil
确实,它失败了。所以问题是:我怎样才能让它正常工作?
【问题讨论】:
-
我认为不可能。 unform 可以恢复数据的形状,但不能恢复类型……因为没有指定类型,只是一个谓词。
-
@Hoagy 你是否已经尝试过 s/merge 而不是 s/and ?(clojure.github.io/clojure/branch-master/…)
-
@TimothyPratley 但这是正确的行为吗?我想不是。这不是一个直接的模拟,但我认为当前的行为就像
unform在conformed 上设置(s/and int? pos?)的值并获得一个浮点数。好像没有错吧? -
@JeroenvanDijk 我没有,但那是因为
s/merge用于地图验证规范,而这不是。 -
@HoagyCarmichael 你说得对,现在不可能。和这个问题一样:dev.clojure.org/jira/browse/…。也许你可以投票?
标签: clojure clojurescript