Advertisement
Guest User

Untitled

a guest
Jun 19th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.19 KB | None | 0 0
  1. ;; Reader Monad
  2.  
  3. (def reader-m
  4. {:return (fn [a]
  5. (fn [_] a))
  6. :bind (fn [m k]
  7. (fn [r]
  8. ((k (m r)) r)))})
  9.  
  10. (defn ask [] identity)
  11. (defn asks [f]
  12. (fn [env]
  13. (f env)))
  14.  
  15. (defn connect-to-db []
  16. (do-m reader-m
  17. [db-uri (asks :db-uri)]
  18. (prn (format "Connected to db at %s" db-uri))))
  19.  
  20. (defn connect-to-api []
  21. (do-m reader-m
  22. [api-key (asks :api-key)
  23. env (ask)]
  24. (prn (format "Connected to api with key %s" api-key))))
  25.  
  26. (defn run-app []
  27. (do-m reader-m
  28. [_ (connect-to-db)
  29. _ (connect-to-api)]
  30. (prn "Done.")))
  31.  
  32. ((run-app) {:db-uri "user:passwd@host/dbname" :api-key "AF167"})
  33. ;; "Connected to db at user:passwd@host/dbname"
  34. ;; "Connected to api with key AF167"
  35. ;; "Done."
  36.  
  37. user=> (def hundred-times (partial * 100))
  38. #'user/hundred-times
  39.  
  40. user=> (hundred-times 5)
  41. 500
  42.  
  43. user=> (hundred-times 4 5 6)
  44. 12000
  45.  
  46. (def doubler
  47. (partial * 2))
  48.  
  49. (def plus-oner
  50. (partial + 1))
  51.  
  52. (defn super-reader
  53. [env]
  54. (let [x (doubler env)
  55. y (plus-oner env)]
  56. (+ x y)))
  57.  
  58. (def super-reader
  59. (do-m reader-m
  60. [x doubler
  61. y plus-oner]
  62. (+ x y)))
  63.  
  64. (defmacro do-reader
  65. [bindings & body]
  66. (let [env (gensym 'env_)
  67. partial-env (fn [f] (list `(partial ~f ~env)))
  68. bindings* (mapv #(%1 %2) (cycle [identity partial-env]) bindings)]
  69. `(fn [~env] (let ~bindings* ~@body))))
  70.  
  71. (def sample-bindings {:count 3, :one 1, :b 2})
  72.  
  73. (def ask identity)
  74.  
  75. (def calc-is-count-correct?
  76. (do-reader [binding-count :count
  77. bindings ask]
  78. (= binding-count (count bindings))))
  79.  
  80. (calc-is-count-correct? sample-bindings)
  81. ;=> true
  82.  
  83. (defn local [modify reader] (comp reader modify))
  84.  
  85. (def calc-content-len
  86. (do-reader [content ask]
  87. (count content)))
  88.  
  89. (def calc-modified-content-len
  90. (local #(str "Prefix " %) calc-content-len))
  91.  
  92. (calc-content-len "12345")
  93. ;=> 5
  94.  
  95. (calc-modified-content-len "12345")
  96. ;=> 12
  97.  
  98. (def example1
  99. (do-reader [a :foo
  100. b :bar]
  101. (+ a b)))
  102.  
  103. (example1 {:foo 2 :bar 40 :baz 800})
  104. ;=> 42
  105.  
  106. (def example2
  107. (do-reader [[a b] (juxt :foo :bar)]
  108. (+ a b)))
  109.  
  110. (example2 {:foo 2 :bar 40 :baz 800})
  111. ;=> 42
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement