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

欢迎!想了解更多的信息,请查看关于页面。

0
Spec
every-kv 文档中说明 "接受单独的键和值前缀并作用于关联集合"。向量对于(associative?)返回 true,但目前不起作用


user=> (s/conform (s/every-kv any? any?) [])
[]
user=> (s/conform (s/every-kv any? any?) [1 2 3])
:clojure.spec/invalid
user=> (s/conform (s/every-kv integer? string?) [])
[]
user=> (s/conform (s/every-kv integer? string?) ["x"])
:clojure.spec/invalid


另一个类似的问题


(s/explain-data (s/every-kv int? int?) [{:a :b}])
UnsupportedOperationException nth 不支持该类型:PersistentArrayMap  clojure.lang.RT.nthFrom (RT.java:903)


*原因:* 向量不应该与 every-kv 一起使用。every-kv 和 every-impl 的组合假设传递给 every-kv 的集合可以提供映射条目的序列。在解释的情况下,由 every-kv 创建的 ::kfn 用于使用键而不是元素索引创建更好的路径段。kfn 假设集合的元素可以调用 `(nth entry 0)` 在元素上。在上述解释失败的情况下,映射 {:a :b} 将在调用 nth 时抛出。

*提议:* 执行以下操作,使要求 coll 元素是映射条目的要求更清晰

* 修改文档字符串,将其改为 "映射的序列" 而不是 "是映射"
* 修改 kfn 以添加检查元素是否是条目,如果是,则使用它的键。如果不是,则使用元素的索引(元素的本身)。在这种情况下,当传递一个条目时,它将报告实际的键;当传递不是条目的事物时,它将报告非条目的集合基于索引。

在打补丁之后,explain-data 调用将提供有用的错误而不是上述异常


user=> (s/explain-data (s/every-kv int? int?) [{:a :b}])
#:clojure.spec.alpha{:problems ({:path [], :pred vector?, :val {:a :b}, :via [], :in [0]})}



*补丁:* clj-2080-8.patch

8 答案

0

评论者:alexmiller

目前,我倾向于说 every-kv 中的文档应该更严格,说 "映射" 而不是 "关联集合",但我将和 Rich 商量。

0

评论者:alexmiller

更新以适应master

0

评论者:alexmiller

更新补丁以适应spec.alpha。

0
_由stu_发表的评论

请更新此票据,包括描述中所示示例的预期行为,以及显示预期行为的测试。  我依然看到向量在符合时失败。


(s/explain-data (s/every-kv integer? string?) ["x"])
=> #:clojure.spec.alpha{:problems ({:path [], :pred vector?, :val "x", :via [], :in [0]})}
0

评论者:alexmiller

向量应该失败 - every-kv需要一个map条目的序列。该补丁在文档字符串中对此进行了说明,并修复了在生成explain-data时可能(错误地)抛出的异常。我更新了标题,描述在行为后包括explain-data,并在补丁中添加了一个测试。

0

评论者:alexmiller

一段时间前丢失了文档字符串更改,已经在-7补丁中重新添加。

0

评论者:alexmiller

-8更新适用于master,没有任何语义变化

0
...