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

欢迎!请访问关于页面以获取更多有关此功能的信息。

+1
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)
  [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

评论者: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/unform}} 的 {{s/?}} 将引入一个额外的嵌套级别。当子项是正则表达式时,我们正在消耗同一“级别”的序列,因此 unform 不应该引入额外的级别。然而在其他情况下(非正则操作),我们 *should* 仍然可能产生嵌套集合。

之前的补丁过于激进:它解包了几乎所有 {{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/op-unform}} 内部我想不出合适的测试用例。(我不确定 {{::s/accept}} 是否在 {{s/op-unform}} 内部实际可达?)
0
by

评论者:alexmiller

感谢你为这个项目工作 - 我有机会时会查看。

0
by

评论者:favila

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

0
by

评论者:favila

由于其他提交加入的测试,补丁不能再干净地应用到主分支上。补丁已重构成主分支。

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