Clojure有许多用于生成测试的库,例如test.check,test.generative或data.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的宏,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)
看起来我的类型暗示了错误的东西,或者元数据没有被传递.除了针对当前问题的修复之外,如果你可以帮助解决更普遍的"元"问题,那么奖励积分:如何调试操作元数据的宏作为宏扩展在这里不是很有用.. …
我想将任何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的人,这个算法:
但是,以这种方式创建BigDecimal的过程是次优的:
有哪些替代方案可以加速它并尽可能减少生成的数量,同时保留上述的唯一性和排序属性?
注意:该解决方案没有生成BigDecimal,它只需要生成一个数字,但我不知道如何使用BigInteger使其工作.此外,我意识到该函数可以被记忆以加速后续执行,但我在初始执行后性能提高.