What's the idiomatic way to keep track of previous values in 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
)
))
Im using a for loop to iterate through a sequence but perhaps I should use a regular loop and recur? Would a map/reduce be useful here?
Be careful -- in Clojure, it's better to think of for
not as a loop, but as a list comprehension -- it takes a collection and returns a modified/filtered version of that collection.
You can do this more idiomatically (in a more functional programming style) by using loop and recur, something like this:
(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])))
Each time you iterate through with new values for last-state
, last-action
and last-reward
, the (if-let [sample (first samples)]
part determines whether there are any samples left to look at -- if there aren't, that means you're at the end of the list, and (first '())
will return nil
, so your results will be returned in whatever form you'd like -- see the last line, where I just returned them as a vector. If there are still samples left, we bind the first one to the symbol sample
, which you can use for your updated calculations of last-state
, etc., then recur
with these updated values and (next samples)
, which is everything after the first sample in that list.
EDIT: I would generally try and do things using map/reduce whenever I can, but whenever you are trying to do a complicated looping operation where you're tallying and calculating a handful of different statistics, loop/recur is usually the best way to go.
@DaveYarwood alluded to map
/ reduce
in his answer ; here's how you could implement it:
(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/66882.html