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

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

+1
Spec
使用包含某些嵌套在某个{{?}}中的 specs 的 {{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

评论由: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不应引入额外的级别。然而在其他情况下(非正则操作),我们*应该*仍然可能会产生嵌套的集合。

之前的补丁太激进:它解包了 {{s/?}} 的所有子-unforms。此补丁 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

评论由:alexmiller 提供

谢谢您为此工作 - 我会找机会看看。

0

评论者:favila

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

0

评论者:favila

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

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