2024年Clojure调查中分享您的想法!

欢迎!请查看关于页面,了解更多关于如何使用本页面的信息。

+1
Spec
使用由一些嵌套在some {{?}}中的cat组成的spec调用{{conform}}和{{unform}},会在结果中创建额外的嵌套层级


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

(let [spec (s/? (s/cat :foo #{:foo}))
      initial [:foo]
      conformed (s/conform spec initial)
      unformed (s/unform spec conformed)]
  [initial 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
by

由:alexmiller发表的评论

好吧,可能我收回之前的说法,他们可能有联系。

0
by

由:bbloom发表的评论

我刚刚在尝试理解一些定义形式时遇到了这个问题。这里有一个例子

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

0
by

由:[email protected]发表的评论

这似乎就是所需的所有内容。

0
by
_由:favila_发表的评论

这个问题实际上比{{(? (cat ...))}}更普遍。当子操作是一个正则表达式时,{{s/unform}}一个{{s/?}}将引入额外的嵌套层次。当子项是正则表达式时,我们正在消耗同样的“级别”序列,因此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合约的一部分。然而,这是一个很大的bug。)

我还为{{s/?}}的每个可能的子操作添加了测试,除了{{::s/accept}},因为我无法想出一个测试用例。(我不确定{{::s/accept}}是否真的在{{s/op-unform}}中使用?)
0
by

由:alexmiller发表的评论

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

0

评论由:favila 发布

我稍微修改了我的补丁(同名):有一个测试案例没有测试正确的东西。

0

评论由:favila 发布

由于其他提交的测试,补丁不再干净地应用于master;补丁已重构到master

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