小编opt*_*evo的帖子

在clojure中使用生成测试库,使用更高阶函数构建自己的库

Clojure有许多用于生成测试的库,例如test.check,test.generativedata.generators.

可以使用更高阶函数来创建可组合的随机数据生成器,例如:

(defn gen [create-fn content-fn lazy]
  (fn [] (reduce #(create-fn %1 %2) (for [a lazy] (content-fn)))))

(def a (gen str #(rand-nth [\a \b \c]) (range 10)))
(a)

(def b (gen vector #(rand-int 10) (range 2)))
(b)

(def c (gen hash-set b (range (rand-int 10))))
(c)
Run Code Online (Sandbox Code Playgroud)

这只是一个示例,可以使用不同的参数,过滤器,局部等进行修改,以创建非常灵活的数据生成功能.

是否存在任何生成库可以做的事情,而不仅仅是(或更多)通过编写一些更高阶函数可以简洁地实现?

作为stackoverflow众神的旁注:我不相信这个问题是主观的.我不是要求哪个库更好.我想知道任何/所有数据生成库的哪些特定特征或技术将它们与组成香草高阶函数区分开来.一个示例答案应该说明使用任何库生成随机数据,并解释为什么通过以上面说明的方式组合HOF来做更复杂的事情.

clojure generative-testing

3
推荐指数
1
解决办法
241
查看次数

在Clojure宏中键入提示deftype

我正在尝试创建一个生成Clojure的宏,deftype并且需要生成类型提示.我目前有一些测试代码:

(defmacro test-macro [n]
  (let [obj-sym (gensym "obj")
    p0 (with-meta 'p0 {:tag java.lang.Object})
    p1 (with-meta 'p1 {:tag java.lang.Integer/TYPE})
    r0 (with-meta 'remove {:tag java.lang.Boolean/TYPE})
    r1 (with-meta 'remove {:tag java.lang.Object})]
`(deftype ~n [~obj-sym]
   java.util.List
   (~r0 [_ ~p0] (.remove ~obj-sym ~p0))
   (~r1 [_ ~p1] (.remove ~obj-sym ~p1)))))
Run Code Online (Sandbox Code Playgroud)

当它返回时:

(test-macro test-it)
;clojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException: Must hint overloaded method: remove, ...
Run Code Online (Sandbox Code Playgroud)

作为指导,它应该产生相当于:

(clojure.core/deftype ThisWorks [obj-5546]
  java.util.List
   (#^"boolean" remove [_ ^java.lang.Object p0-object] (.remove obj-5546 p0-object))
   (^{:tag "java.lang.Object"} remove [_ ^int p0-int] (.remove obj-5546 p0-int)))
Run Code Online (Sandbox Code Playgroud)

看起来我的类型暗示了错误的东西,或者元数据没有被传递.除了针对当前问题的修复之外,如果你可以帮助解决更普遍的"元"问题,那么奖励积分:如何调试操作元数据的宏作为宏扩展在这里不是很有用.. …

macros clojure

2
推荐指数
1
解决办法
625
查看次数

有效地将任何字符串映射到表示字符串的字典顺序的唯一数字

我想将任何unicode字符串转换为唯一的数字(在Clojure或Java中).我希望生成的数字具有以下属性: - 它对于该字符串是唯一的 - 当一组这样的数字被排序并映射回原始字符串时,字符串将按排序顺序出现.字符串并非事先都知道.

可以这样做的一种方法是:

(defn strval [^String s]
    (bigdec (reduce #(str %1 (format "%05d" (int %2))) "0." s)))
Run Code Online (Sandbox Code Playgroud)

我们可以通过以下方式验证排序顺序是否正确

(assert (< (strval "a") (strval "b")))
(assert (< (strval "a") (strval "aa")))
(assert (< (strval "aa") (strval "ab")))
Run Code Online (Sandbox Code Playgroud)

(忽略,如果你喜欢"int"不一定是获得单个角色的排序顺序的最佳方式.)

对于那些不熟悉Clojure的人,这个算法:

  1. 将字符串转换为字符序列
  2. 获取一个字符的整数值
  3. 将此整数转换为字符串并用零填充它,以便它生成一个包含五个字符的字符串.
  4. 将此字符串追加到以"0"开头的结果字符串.
  5. 如果有更多字符则返回步骤2,否则返回步骤2
  6. 将结果字符串转换为Java BigDecimal

但是,以这种方式创建BigDecimal的过程是次优的:

  1. 它依赖于数字和字符串之间的转换,然后返回到最终的数字.
  2. 用零填充每个值不会产生最紧凑的表示.

有哪些替代方案可以加速它并尽可能减少生成的数量,同时保留上述的唯一性和排序属性?

注意:该解决方案没有生成BigDecimal,它只需要生成一个数字,但我不知道如何使用BigInteger使其工作.此外,我意识到该函数可以被记忆以加速后续执行,但我在初始执行后性能提高.

java sorting string hash clojure

1
推荐指数
1
解决办法
244
查看次数

标签 统计

clojure ×3

generative-testing ×1

hash ×1

java ×1

macros ×1

sorting ×1

string ×1