Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;; Reader Monad
- (def reader-m
- {:return (fn [a]
- (fn [_] a))
- :bind (fn [m k]
- (fn [r]
- ((k (m r)) r)))})
- (defn ask [] identity)
- (defn asks [f]
- (fn [env]
- (f env)))
- (defn connect-to-db []
- (do-m reader-m
- [db-uri (asks :db-uri)]
- (prn (format "Connected to db at %s" db-uri))))
- (defn connect-to-api []
- (do-m reader-m
- [api-key (asks :api-key)
- env (ask)]
- (prn (format "Connected to api with key %s" api-key))))
- (defn run-app []
- (do-m reader-m
- [_ (connect-to-db)
- _ (connect-to-api)]
- (prn "Done.")))
- ((run-app) {:db-uri "user:passwd@host/dbname" :api-key "AF167"})
- ;; "Connected to db at user:passwd@host/dbname"
- ;; "Connected to api with key AF167"
- ;; "Done."
- user=> (def hundred-times (partial * 100))
- #'user/hundred-times
- user=> (hundred-times 5)
- 500
- user=> (hundred-times 4 5 6)
- 12000
- (def doubler
- (partial * 2))
- (def plus-oner
- (partial + 1))
- (defn super-reader
- [env]
- (let [x (doubler env)
- y (plus-oner env)]
- (+ x y)))
- (def super-reader
- (do-m reader-m
- [x doubler
- y plus-oner]
- (+ x y)))
- (defmacro do-reader
- [bindings & body]
- (let [env (gensym 'env_)
- partial-env (fn [f] (list `(partial ~f ~env)))
- bindings* (mapv #(%1 %2) (cycle [identity partial-env]) bindings)]
- `(fn [~env] (let ~bindings* ~@body))))
- (def sample-bindings {:count 3, :one 1, :b 2})
- (def ask identity)
- (def calc-is-count-correct?
- (do-reader [binding-count :count
- bindings ask]
- (= binding-count (count bindings))))
- (calc-is-count-correct? sample-bindings)
- ;=> true
- (defn local [modify reader] (comp reader modify))
- (def calc-content-len
- (do-reader [content ask]
- (count content)))
- (def calc-modified-content-len
- (local #(str "Prefix " %) calc-content-len))
- (calc-content-len "12345")
- ;=> 5
- (calc-modified-content-len "12345")
- ;=> 12
- (def example1
- (do-reader [a :foo
- b :bar]
- (+ a b)))
- (example1 {:foo 2 :bar 40 :baz 800})
- ;=> 42
- (def example2
- (do-reader [[a b] (juxt :foo :bar)]
- (+ a b)))
- (example2 {:foo 2 :bar 40 :baz 800})
- ;=> 42
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement