Skip to content

Instantly share code, notes, and snippets.

@budu
Created April 17, 2012 02:43
Show Gist options
  • Save budu/2403046 to your computer and use it in GitHub Desktop.
Save budu/2403046 to your computer and use it in GitHub Desktop.
Poor's man state monad!
(defmacro << [k-or-ks f]
`(fn [state#]
(update-in state#
~(if (vector? k-or-ks)
k-or-ks
(vector k-or-ks))
~f)))
(defn >>* [state form]
(condp = (first form)
'>>> `(fn [~state] ~@(rest form) ~state)
'<<< `(fn [~state] ~@(rest form))
form))
(defmacro >> [state & forms]
(reduce #(list (if (#{'<< 'fn 'fn*
'clojure.core/fn
'clojure.core/fn*} (first %2))
%2
`(fn [s#] ~%2 s#)) %)
(conj (map (partial >>* state) forms)
state)))
;; user> (let [state {}]
;; (>> state
;; (println "side-effect")
;; (>>> (println state))
;; (<< [:a :b] (constantly []))
;; (>>> (println state))
;; (<< [:a :b] #(conj % 1 2 3))
;; (<<< (state :a))
;; (>>> (println state))
;; (<< [:b 1] #(inc %))
;; (println state)
;; (<<< (state :b))))
;; side-effect
;; {}
;; {:a {:b []}}
;; {:b [1 2 3]}
;; {}
;; => [1 3 3]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment