在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-statelast-actionlast-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?

下一篇: idiomatic way of extending clojure reify