Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns sandbox.monad)
- (defn merge-meta
- [x m]
- (vary-meta x merge m))
- (defn copy-meta
- [x m]
- (merge-meta x (meta m)))
- (defprotocol Monad
- :extend-via-metadata true
- (bind [this f]))
- (defn maybe-nothing
- [x]
- (merge-meta x {:nothing? true}))
- (defn maybe-just
- [x]
- (merge-meta x {:nothing? false}))
- (defn maybe-wrap-nil
- [f]
- (fn [m]
- (if-let [n (f m)]
- (maybe-just n)
- (maybe-nothing m))))
- (defn maybe
- [x]
- (letfn [(bind' [this f]
- (if (:nothing? (meta this))
- this
- (merge-meta (f this)
- (dissoc (meta this) :nothing?))))]
- (merge-meta x {`bind bind'
- :nothing? (not x)})))
- (defn or-else
- [m else]
- (if-not (:nothing? (meta m))
- m
- else))
- (defn inc-if-not-3
- [[x]]
- (when-not (= x 3)
- [(inc x)]))
- (def monadic-inc-if-not-3 (maybe-wrap-nil inc-if-not-3))
- (or-else (bind
- (bind
- (bind
- (maybe [3])
- monadic-inc-if-not-3)
- monadic-inc-if-not-3)
- monadic-inc-if-not-3)
- "foo")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement