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

欢迎!有关如何使用本站的信息,请参见关于页面。

+1
规范
自定义生成器可能会在规范生成器上构建(通过 fmap/bind)。顶层生成器重写将不会在自定义生成器内部起作用


(require '[clojure.spec :as s])
(require '[clojure.test.check.generators :as gen])

;; 一个包含单个整数值的映射
(s/def ::val integer?)
(s/def ::body (s/keys :req [::val]))

;; 此规范与 'body' 的字符串化版本匹配。
;; (read-string 仅用于演示目的)
(s/def ::stringy-body
  (s/with-gen
    (s/and string? #(s/valid? ::body (read-string %)))
    #(gen/fmap pr-str (s/gen ::body))))

(s/valid? ::stringy-body "{:user/val 37}") ;; => true

;; 如预期生成各种字符串化映射
(take 3 (gen/sample (s/gen ::stringy-body)))
;; => ("#:user{:val -1}" "#:user{:val 0}" "#:user{:val -1}")

;; *** 但重写没有被传递 ***
(take 3 (gen/sample (s/gen ::stringy-body {::val #(s/gen #{42})})))
;; ("#:user{:val -1}" "#:user{:val 0}" "#:user{:val 0}")


考虑在 s/gen、s/with-gen 等中记录这一点。

5 答案

0

评论由:alexmiller提供

当您使用 with-gen 时,实际上是在覆盖内置的 gen 机制(支持覆盖)并提供自己的(对规范不可见)生成器。您不应该期望重写会在自定义生成器内部起作用。

0

评论由:mullr提供

这很有道理,但按照我的预期(和搜寻过程),我期望从传递给 s/with-gen 的函数中获取重写映射,但并没有找到这样的方法。

0

评论由:mullr提供

... 我第一次没有完全理解你的评论。从实现中可以看出,自定义生成器(内部 gfn)从未接收过内置规范所拥有的任何上下文信息。既然这听起来是故意的,那么在 s/gen 或 s/with-gen 的文档字符串中记录这个限制将是有用的。

0

评论由:alexmiller提供

这不是一个疯狂的想法,但是看起来在当前的实现中,没有进行一些相当重大的更改是无法实现的。

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