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

欢迎!请参阅关于页面了解更多关于该操作的信息。

+1
规范
生成器重写无法按预期在多规范上工作。
下面的代码说明了问题。

{code:none}
(s/def ::obj-type #{:a :b})

(s/def ::base-obj (s/keys :req [::obj-type]))

(defmulti obj-type ::obj-type)
(defmethod obj-type :a [_]
  ::base-obj)
(defmethod obj-type :b [_]
  ::base-obj)

(s/def ::obj (s/multi-spec obj-type ::obj-type))


{code:none}
(gen/sample (s/gen ::obj {::obj-type #(gen/return :a)}))

在上面的例子中,多方法的调度函数 *::obj-type* 被赋予了生成器改写。
预期只返回 *{::obj-type :a}* 的集合
实际上它也会返回 *{::obj-type :b}*.  
这意味着生成器不能用来约束样本中调度键的集合。

h2. 当前方法
在多方法的情况下,为每个可能的调度值构建一个生成器。
然后随机选择一个,而不会关注调度函数(键)的重写。

h2. 修复方法
可用的提交 [这里|https://github.com/bonega/spec.alpha/commit/9cb42478b52eac275d496ec29669e2bf4b3e8e1f]
修复版本在调度值方面构建生成器与原始版本完全相同。
之后会检查是否存在对调度函数的重写。
如果存在,则使用重写生成器进行 gen/bind。
bind 函数从重写生成器中生成一个值。
然后使用该值查找并返回正确的多方法生成器。

[测试案例|https://pastebin.com/62ZT5Zfc]

6 答案

0

评论者:bonega

提供了问题修复补丁。

0

评论者:alexmiller

请将导致问题的代码移动到描述中,并解释问题和更改。

0
_评论者:[email protected]_

我无法弄清如何编辑描述...

描述
在多方法的情况下,为每个可能的调度值构建一个生成器。
这时候会随机选择一个,而不考虑为 dispatch-fn(key) 设置的覆盖。

提交:https://github.com/bonega/spec.alpha/commit/9cb42478b52eac275d496ec29669e2bf4b3e8e1f
我的补丁通过检查是否存在对 dispatch-fn 的覆盖来修复这个问题。
如果有的话,会对覆盖生成器执行 gen/bind,并使用结果查找正确的多方法生成器。

测试案例:https://pastebin.com/62ZT5Zfc
预期测试将通过。
基本上,我想要使用像 (gen/generate (s/gen ::obj {::obj-type #(gen/return :a)})) 这样的覆盖生成器来生成 ::obj。
预期结果始终应该是 `{::obj-type :a}`。
以前,即使指定了覆盖,输出也可能为 :b。
0

评论者:alexmiller

我已经为你提供了编辑权限,以便你可以进行更新...

0

评论者:[email protected]

我已经更新了描述。
如果有什么不清楚的地方,请告诉我。

0
...