用于进度报告的惯用 clojure? [英] Idiomatic clojure for progress reporting?

查看:25
本文介绍了用于进度报告的惯用 clojure?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该如何监控 clojure 中映射函数的进度?

How should I monitor the progress of a mapped function in clojure?

在使用命令式语言处理记录时,我经常每隔一段时间打印一条消息来表明事情已经走了多远,例如每 1000 条记录报告一次.本质上,这是计算循环重复次数.

When processing records in an imperative language I often print a message every so often to indicate how far things have gone, e.g. reporting every 1000 records. Essentially this is counting loop repetitions.

我想知道在 clojure 中我可以采取哪些方法来将函数映射到我的记录序列上.在这种情况下,打印消息(甚至记录进度)似乎本质上是副作用.

I was wondering what approaches I could take to this in clojure where I am mapping a function over my sequence of records. In this case printing the message (and even keeping count of the progress) seem to be essentially side-effects.

到目前为止我想出的东西是这样的:

What I have come up with so far looks like:

(defn report
  [report-every val cnt]
  (if (= 0 (mod cnt report-every))
    (println "Done" cnt))
    val)

(defn report-progress
  [report-every aseq]
  (map (fn [val cnt] 
          (report report-every val cnt)) 
       aseq 
       (iterate inc 1)))

例如:

user> (doall (report-progress 2 (range 10)))
Done 2
Done 4
Done 6
Done 8
Done 10
(0 1 2 3 4 5 6 7 8 9)

还有其他(更好的)方法可以达到这种效果吗?

Are there other (better) ways of achieving this effect?

我在做的事情有什么缺陷吗?(我想我是在保持懒惰而不是举个例子.)

Are there any pitfalls in what I am doing? (I think I am preserving laziness and not holding the head for example.)

推荐答案

Clojure 的优点是您可以将报告附加到数据本身,而不是执行计算的代码.这允许您将这些逻辑上不同的部分分开.这是我的 misc.clj 中的一个块,我发现我几乎在每个项目中都使用了它:

The great thing about clojure is you can attach the reporting to the data itself instead of the code that does the computing. This allows you to separate these logically distinct parts. Here is a chunk from my misc.clj that I find I use in just about every project:

(defn seq-counter 
  "calls callback after every n'th entry in sequence is evaluated. 
  Optionally takes another callback to call once the seq is fully evaluated."
  ([sequence n callback]
     (map #(do (if (= (rem %1 n) 0) (callback)) %2) (iterate inc 1) sequence))
  ([sequence n callback finished-callback]
     (drop-last (lazy-cat (seq-counter sequence n callback) 
                  (lazy-seq (cons (finished-callback) ())))))) 

然后将报告器包裹在您的数据周围,然后将结果传递给处理函数.

then wrap the reporter around your data and then pass the result to the processing function.

(map process-data (seq-counter inc-progress input))

这篇关于用于进度报告的惯用 clojure?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆