请分享您的想法,参加<萝卜链接 style="color:#34495e;" href="https://www.surveymonkey.com/r/clojure2024">2024年Clojure调查!

欢迎!请参阅关于页面了解有关这项工作的更多信息。

0票 <元itemprop="upvoteCount" content="0">
<时间itemprop="dateCreated" datetime="2014-04-02T22:55:00+0000" 时标题="2014-04-02T22:55:00+0000">4月2日,2014年 test.check
我认为{{clojure.core/for}}的语法与test.check的组合器非常契合。例如:


(defn gen-even-subset
  "返回一个生成器,该生成器生成交替基数
   给定元素的子集"
  [元素]
  (gen/for [布尔值 (apply gen/tuple (重复(元素计数) gen/boolean))
        :let [true-count (->> 布尔值 (过滤真实身份) (大小)]]
    :when (even? true-count)]
    (->> (map列表 布尔值 元素)
        (过滤器第一)
        (映射第二)
    )))


这结合了{{fmap}}、{{bind}}和{{such-that}}的能力,采用了熟悉的语法。

这里的一个缺点是使用多个子句用于独立的生成器会诱使使用{{gen/bind}},而似乎{{gen/tuple}}会更简单且更容易缩小。针对这种方法的解决方案是添加一个额外的受支持的子句,可能称为{{:parallel}},它使用{{:let}}的语法来提供{{gen/tuple}}的功能


(gen/for [:parallel [n1 gen/nat
         (({gen/nat}
         :let [sum (+ n1 n2)]]
 {:nums [n1 n2] :sum sum})


与{{gen/tuple}}相比,这种方法的优势在于将生成器在语法上放置在名称旁边,而不是将生成器与名称分开。

当前补丁中没有添加{{:parallel}}功能。

10 个答案

0票 <元itemprop="upvoteCount" content="0">
<时间itemprop="dateCreated" datetime="2014-04-05T21:23:25+0000" 时标题="2014-04-05T21:23:25+0000">4月5日,2014年
_评论者:gfredericks_

我认为关于{{:when}}的含义可能存在某些设计歧义。特别是,在以下人造例子中:


(for [n nat
      v (向量(返回n))
      :let [sum (减少+ v)]
      :when (正sum)]
  v)


在我的默认设计式中,这可能导致挂起,原因与该代码可能导致挂起的原因相同


(nat bind
      (fn [n]
        (such-that
          (fn [v] (pos? (reduce + v))))
          (vector (return n)))))


但它也可以写成


(such-that
  (fn [v] (pos? (reduce + v))))
  (bind nat (fn [n] (vector (return n)))))


所以问题是是否将{{:when}}过滤器仅应用于之前的生成器,还是应用到所有的之前生成器。我有一种模糊的感觉,认为后者在某些情况下可能效率较低,但我不确定具体情况是什么。所以我认为我们的选择有:

#决定始终以某种方式执行或以另一种方式执行
##提供一个第三关键字({{:when-all}}?)以实现不同的行为
##不编写这个宏,因为太难理解

我的直觉是选择选项1,仅将:when应用于之前的生成器。
0票 <元itemprop="upvoteCount" content="0">

评论者:gfredericks

附上我的初步草案。实现所需的思考比预期的多,因此我包含了说明宏结构的内联注释。

0票 <元itemprop="upvoteCount" content="0">

评论者:gfredericks

已附件TCHECK-15-p1.patch,更新以应用当前的master版本。

0票 <元itemprop="upvoteCount" content="0">

评论者:gfredericks

已附件TCHECK-15-p2.patch,在文档字符串中添加了有关独立子句、收缩和元组的说明。

0票 <元itemprop="upvoteCount" content="0">

评论者:gfredericks

已附件TCHECK-15-p3.patch,修复了一个错误和一个在命名空间别名中的冗余。

0票 <元itemprop="upvoteCount" content="0">

评论者:gfredericks

已附件TCHECK-15-p4.patch,修复了关于解构的问题(并添加了一个回归测试)。

0票 <元itemprop="upvoteCount" content="0">

评论者:gfredericks

还可能有用的是,我将它放入了我的test.check实用工具库中: https://github.com/fredericksgary/test.chuck#for

0票 <元itemprop="upvoteCount" content="0">

评论者:michaelblume

我想知道是否可以通过分析代码并检查绑定是否可以并行运行来避免:parallel?

0票 <元itemprop="upvoteCount" content="0">

评论者:gfredericks

理论上这是可能的,但我们需要访问一个无错误的代码分析器。

此外,你可能还会认为这会使代码的含义变得更微妙。

0票 <元itemprop="upvoteCount" content="0">
参考:https://clojure.atlassian.net/browse/TCHECK-15 (由gfredericks报告)
...