By default, Clojure does not have a monadic composition. For this you need libraries like algo.monads or fluokitten .
The monoid in Haskell and Skalaz is a class that implements three functions:
mempty returns an identity elementmappend combines two values ββof the same typemconcat used to convert collections of this type to elements and vv
Clojure does not have a fold function that calls all three of them; reduce is a function of returning to a higher order for accumulation over a collection.
By default, it accepts 3 parameters: gear function, battery and collection. The reducer function is used to combine the battery and one element from the collection at the same time. It should not accept the same types as mappend . The third is always a collection, so mconcat not required.
In the context of Clojure 1,5 clojure.reducers and clojure.core/reduce there is a monoid: a function that returns an identification element when called without parameters.
For instance:
(+) => 0 (*) => 1 (str) => "" (vector) => [] (list) => ()
This monoid function is used as a reducer in the two-parameter version of reduce ; its "monoidal identity" or mempty is called to create the initial battery.
(reduce + [1 2 3]) => (reduce + (+) [1 2 3]) => (reduce + 0 [1 2 3])
So, if you want to translate the examples here, you need to find or create a function that has such an implementation of the "monoid" to use it in reducing the arc.
For disjunction, Clojure has or :
(defmacro or "Evaluates exprs one at a time, from left to right. If a form returns a logical true value, or returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression. (or) returns nil." {:added "1.0"} ([] nil) ([x] x) ([x & next] `(let [or# ~x] (if or# or# (or ~@next )))))
He has an implementation of the "monoid", ([] nil) . However, or is implemented as a macro to support a short circuit and can only be used in an expression that needs to be expanded, and not as a function parameter:
(reduce or [false true false true true]) CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling
So, we need a βnewβ or , which is a true function for disjunction. It should also implement a no-arity version returning zero:
(defn newor ([] nil) ([fs] (if ffs)))
So, now we have a function with the implementation of the "monoid", and you can use it to reduce the arc:
(reduce newor [true false true true]) => true
It seems a bit complicated until you understand why Clojure implemented or as a macro with multiple arity
(or true false true true) => true