Advertisement
Guest User

Untitled

a guest
Jan 24th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (ns sandbox.monad)
  2.  
  3. (defn merge-meta
  4.   [x m]
  5.   (vary-meta x merge m))
  6.  
  7. (defn copy-meta
  8.   [x m]
  9.   (merge-meta x (meta m)))
  10.  
  11. (defprotocol Monad
  12.   :extend-via-metadata true
  13.   (bind [this f]))
  14.  
  15. (defn maybe-nothing
  16.   [x]
  17.   (merge-meta x {:nothing? true}))
  18.  
  19. (defn maybe-just
  20.   [x]
  21.   (merge-meta x {:nothing? false}))
  22.  
  23. (defn maybe-wrap-nil
  24.   [f]
  25.   (fn [m]
  26.     (if-let [n (f m)]
  27.       (maybe-just n)
  28.       (maybe-nothing m))))
  29.  
  30. (defn maybe
  31.   [x]
  32.   (letfn [(bind' [this f]
  33.             (if (:nothing? (meta this))
  34.               this
  35.               (merge-meta (f this)
  36.                           (dissoc (meta this) :nothing?))))]
  37.     (merge-meta x {`bind bind'
  38.                    :nothing? (not x)})))
  39.  
  40. (defn or-else
  41.   [m else]
  42.   (if-not (:nothing? (meta m))
  43.     m
  44.     else))
  45.  
  46. (defn inc-if-not-3
  47.   [[x]]
  48.   (when-not (= x 3)
  49.     [(inc x)]))
  50.  
  51. (def monadic-inc-if-not-3 (maybe-wrap-nil inc-if-not-3))
  52.  
  53. (or-else (bind
  54.           (bind
  55.            (bind
  56.             (maybe [3])
  57.             monadic-inc-if-not-3)
  58.            monadic-inc-if-not-3)
  59.           monadic-inc-if-not-3)
  60.          "foo")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement