Skip to content

Instantly share code, notes, and snippets.

@bsless
Last active August 30, 2020 07:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bsless/fad4d5eeaf0480bcf65525cbbf743e9b to your computer and use it in GitHub Desktop.
Save bsless/fad4d5eeaf0480bcf65525cbbf743e9b to your computer and use it in GitHub Desktop.
The bare minimum to create a state monad in Clojure. No good reason, really.
(definline pair
[x y]
`(clojure.lang.MapEntry/create ~x ~y))
(defn create-state-monad
[init]
(fn [f in]
(let [state' (f init in)]
(pair (create-state-monad state') state'))))
(def s (create-state-monad 0))
(def s' (s + 1))
(def s'' ((s' 0) + 2))
(def s''' ((s'' 0) + 3))
;;; Other takes
(defn -state
[i]
(reify
clojure.lang.IDeref
(deref [this] i)
clojure.lang.IFn
(invoke [this f x]
(-state (f i x)))))
(defn -accum
[f i]
(reify
clojure.lang.IDeref
(deref [this] i)
clojure.lang.IFn
(invoke [this x]
(-accum f (f i x)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment