(defrecord Game [phases]I then started to think that this would be a good opportunity to use a state monad. I've tried to reimplement the above code using the algo.monads library but the result was less than satisfactory (probably due to my own shortcoming), here's the monadic version:
(next-phase [this]
(stop-timer)
(swap! phases #(conj (vec (rest %)) (first %)))
(log :info "change phase to %s" (key (first @phases)))
(start-phase this))
(defrecord Game [phases]
(next-phase [this]As my code probably doesn't need the full power of the state monad, I tried to write a lighter-weight version using the following macro:
(->
((domonad state-m
[_ (fn [s] (stop-timer) [s s])
_ (update-state
(fn [s]
(update-in s [:phases]
#(conj (vec (rest %)) (first %)))))
_ (fn [s]
(log :info "change phase to %s" (key (first (:phases s)))) [s s])]
nil)
state)
second
start-phase))
(defmacro >> [& state-and-forms]Which let me write:
(reduce #(list (if ('#{fn fn*} (first %2))
%2
`(fn [s#] ~%2 s#)) %)
state-and-forms))
Besides keeping track of the state at every point, it can help with
the reasoning about what should happen next for each state change.
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
You can try using the in-memory version of Datomic.Besides keeping track of the state at every point, it can help with
the reasoning about what should happen next for each state change.