A structure which allows you to represent a computation as a sequence of steps. The monad allows you to decorate each step with additional processing rules.
- Logging
- IO
- Error handling
Allows things like side-effects, IO, etc to be defined in a purely functional manner.
[Do you really need them in Clojure?] (https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CCYQtwIwAA&url=http%3A%2F%2Fwww.infoq.com%2Fpresentations%2FMacros-Monads&ei=guv6UqrZEefH0AHJjICACw&usg=AFQjCNHCXLKjyGgVoCRvJN-M7_h5tN2ISg&sig2=aK0kzDz-EYGuxd4YOZWPSQ&bvm=bv.61190604,d.dmQ)
(let [a (step1)
b (step2 a)
c (step3 b)
...])
(->> foos
(map step1)
(map step2)
(map step3))
Both have difficulty requiring with try/catch or conditional logic to recover from errors at each step.
(->> foos
(map step1)
(map step2)
(map (wrap-check-a step3))
(map (wrap-check a step4))
(map (wrap-check-b (wrap-check-a step5)))
(map (wrap-check-b (wrap-check-a step6)))
...)
(defn wrap-check-a [step] (fn [m] (if (:a m) (step m) m)))
;; MORE scaffolding
(defmonad m-halt-error
m-bind (fn [state step m] (if (and (:check-a state) (not (:a m)) m (step m)))) ;; simplification
...)
(defn ---must-have-a--- [state] (assoc state :check-a true) ;; alter monad state.
;; LESS clutter to core pipeline
(with-monad m-halt-error
(m-chain [step1
step2
---must-have-a---
step3
step4
---must-have-b---
step5
step6
...]))
- Gives you an imperative looking solution (w/ state).
- Reduce clutter to core pipeline.
- AOP.
- Well-known [about].
- Macros & other features in Clojure.
- Cognative load.