在clojure中追踪以前的价值的惯用方法是什么?
(defmethod learn [:SARSA :Module] [learner module]
(let [samples (get learner :dataset)]
(for [seq samples]
(let [laststate (atom 0) lastaction (atom 0) lastreward (atom 0)])
;;Do some stuff
;;Update laststate,lastaction,lastreward
)
))
即时通讯使用循环遍历一个序列,但也许我应该使用一个规则的循环,并重复? map / reduce会在这里有用吗?
要小心-用Clojure,这是更好地认为for
不作为一个循环,但作为一个列表理解-它需要一个集合,并返回该集合的修改/过滤的版本。
你可以通过使用循环和循环来更习惯地(在更多的函数式编程风格中)做到这一点,如下所示:
(defmethod learn [:SARSA Module] [learner module]
(loop [samples (get learner :dataset)
last-state 0
last-action 0
last-reward 0]
(if-let [sample (first samples)]
(recur (next samples) (new-last-state) (new-last-action) (new-last-reward))
[last-state last-action last-reward])))
每次用last-state
, last-action
和last-reward
新值进行迭代时, (if-let [sample (first samples)]
部分确定是否有任何样本需要留意 - 如果没有样本t,这意味着你在列表的最后,并且(first '())
将返回nil
,所以你的结果将以任何你想要的形式返回 - 看到最后一行,我刚刚返回它们的地方作为向量,如果仍有样本剩下,我们将第一个样本绑定到符号sample
,您可以用它来更新last-state
计算等等,然后用这些更新的值和(next samples)
recur
是该列表中的第一个样本之后的所有内容。
编辑:我会尽可能地使用map / reduce来做任何事情,但是无论何时你试图做一个复杂的循环操作,你计算和计算一些不同的统计数据,loop / recur通常是最好的方法走。
@DaveYarwood在他的回答中提到了map
/ reduce
; 以下是您可以如何实现它的方法:
(defmethod learn [:SARSA Module] [learner module]
(reduce (fn [[state action reward] sample]
;; do some stuff and computes new values for state/action/reward
[new-state new-action new-reward])
[0 0 0]
(get learner :dataset)))
链接地址: http://www.djcxy.com/p/66881.html
上一篇: What's the idiomatic way to keep track of previous values in clojure?