2024 Clojure状态调查!分享您的想法。

欢迎!请参阅关于页面,了解更多有关此功能的信息。

+1投票
Spec
使用包含一些嵌套在?中的.cat的spec调用{{conform}}和然后{{unform}}会在结果中创建一个额外的嵌套级别


(require '[clojure.spec :as s])

(let [spec (s/? (s/cat :foo #{:foo}))
      初始 [:foo]
      conformed (s/conform spec initial)
      unformed (s/unform spec conformed)]
  [初始 conformed unformed])
;;=> [[:foo] {:foo :foo} [(:foo)]]


只有{{?}}或{{cat}}单独使用时,并不会出现这种行为


(let [spec (s/? #{:foo})]
  (s/unform spec (s/conform spec [:foo])))
;;=> [:foo]

(let [spec (s/cat :foo #{:foo})]
  (s/unform spec (s/conform spec [:foo])))
;;=> (:foo)


*补丁:* CLJ-2003-corrected.patch

10 个答案

0 投票

评论者:pbrown

我遇到了另一个额外嵌套的案例,当重复一个或多个序列时,如果开始或结束处的可选元素也被另一个端点的元素的条件匹配

user=> (s/conform (s/+ (s/cat :k any? :v (s/? any?))) [:a 1 :b 2]) [{:k :a, :v 1} [{:k :b, :v 2}]]

我期望的是

`[{:k :a, :v 1} {:k :b, :v 2}] `

以下给出了预期的结果

user=> (s/conform (s/+ (s/cat :k any? :v (s/? any?))) [:a 1 :b]) [{:k :a, :v 1} {:k :b}] user=> (s/conform (s/+ (s/cat :k keyword? :v (s/? int?))) [:a 1 :b 2]) [{:k :a, :v 1} {:k :b, :v 2}] user=> (s/conform (s/* (s/cat :k any? :v (s/? any?))) [:a 1 :b 2]) [{:k :a, :v 1} {:k :b, :v 2}]

0 投票

评论者:alexmiller

Phil,我认为你的例子是不同的问题,你应该为这个问题创建一个新的Jira。

0 投票

评论者:alexmiller

好吧,也许我可以收回这句话,它们可能是相关的。

0 投票

评论由:bbloom发布

我在尝试理解一些定义形式时遇到了这个问题。以下是一个例子:

user=> (s/unform :clojure.core.specs/defn-args (s/conform :clojure.core.specs/defn-args '(f (link: & xs))))
(f ((& xs)))

0 投票

评论由:[email protected]发布

这似乎就是所需的所有。

0 投票
_评论由:favila_发布

这个问题实际上比{{(? (cat ...))}}更普遍。当一个{{s/?}}与任何正则表达式子操作符一起使用时,{{s/unform}}将添加一个额外的嵌套级别。当子操作符是正则表达式时,我们消耗相同的“级别”的序列,因此unform不应引入额外的级别。但是在其他情况下(非正则表达式操作),我们*应该*可能产生一个嵌套集合。

上一个补丁太激进:它解包了{{s/?}}的所有子unform。这个修正补丁CLJ-2003-corrected.patch只有当子操作符是正则表达式时才解包。

遗憾的是,我们不能区分所需的但可选的nil和非{{s/?}}的非匹配项。具体来说,以下测试现在成立:


(testing "s/?匹配nil")
  (is (nil? (s/conform (s/? nil?) [nil])))
  (is (nil? (s/conform (s/? nil?) [])))
  (is (nil? (s/conform (s/? nil?) nil)))
  (is (= (s/unform (s/? nil?) nil) [])))


(我没有将这些测试添加到补丁中,因为我不确定它们是否应为unform合同的一部分。然而,这些测试确实有一些大陷阱。)

我还为{{s/?}}的每个可能的子操作添加了测试,除了我无法为此想的{{::s/accept}},我不确定{{::s/accept}}是否实际上可以在{{s/op-unform}}内部到达。(我不确定。)
0 投票
by

评论者:alexmiller

感谢为此工作 - 我有空时会查看。

0 投票
by

评论者:favila

我必须稍微修改我的补丁(同一名称):其中一个测试用例没有测试正确的东西。

0 投票
by

评论者:favila

由于其他提交中添加的测试,补丁不能再干净地应用到master上。Patch rebase到master

0 投票
by
参照: https://clojure.atlassian.net/browse/CLJ-2003 (由 alex+import 报告)
...