anchor.diff:  ;; "Elapsed time: 86.20699 msecs"
   ;; => 85
   ----
  -
  -
  -=== Foldable
  -
  -The *Foldable* is a generic abstraction for data structures that can be folded. It consists
  -mainly on two functions: `foldl` and `foldr`. `foldl` is also known as `reduce` or `inject`
  -in other mainstream programming languages.
  -
  -Both function have an identical signature and differ in how they traverse the data structure.
  -Let's look at a little example using `foldl`:
  -
  -[source, clojure]
  -----
  -(foldl (fn [acc v] (+ acc v)) 0 [1 2 3 4 5])
  -;; => 15
  -----
  -
  -You can observe that `foldl` is identical to the clojure `reduce` function:
  -
  -[source, clojure]
  -----
  -(reduce (fn [acc v] (+ acc v)) 0 [1 2 3 4 5])
  -;; => 15
  -----
  -
  -And the same operation can be done using `foldr`:
  -
  -[source, clojure]
  -----
  -(foldr (fn [v wc] (+ v wc)) 0 [1 2 3 4 5])
  -;; => 15
  -----
  -
  -The main difference between `foldl` and `reduce` is that `foldl` has a fixed arity so all
  -parameters are mandatory and `foldl` is a generic abstraction that can work with other
  -types apart from collections.
  -
  -As we said previously, the `foldl` and `foldr` differ mainly on how they traverse the
  -data structure. Then, for understanding better how they work internally, let's see a
  -graphical representation of the `foldl` execution model:
  -
  -[source, text]
  -----
  -((((acc⊕1)⊕2)⊕3)⊕4)⊕5
  -----
  -
  -In contrast to the `foldr` internal execution model:
  -
  -[source, text]
  -----
  -1⊕(2⊕(3⊕(4⊕(5⊕(wc)))))
  -----
  -
  -In languages with strict argument evaluation, `foldr` does not have many
  -applications because when the data structure to fold grows it tends to consume all the
  -stack (causing the well known stack overflow). In case of Clojure, the unique obvious
  -case of using foldr is for small datastructures.
  -
  -[source, clojure]
  -----
  -(m/foldr #(cons (inc %1) %2) '() (range 100000))
  -;; => StackOverflowError
  -----
  -
  -The *Foldable* abstraction is already implemented for cloure vectors, lazy seqs and ranges
  -plus the cats maybe, either and validation types. Let see an example how it behaves with maybe:
  -
  -[source, clojure]
  -----
  -(m/foldl #(m/return (+ %1 %2)) 1 (maybe/just 1))
  -;; => #<Just 1>
  -
  -(m/foldl #(m/return (+ %1 %2)) 1 (maybe/nothing))
  -;; => 1
  -----
  -
  -It there also other fold functions that are implemented in terms of the basic `foldl`
  -or `foldr` that can be *foldm* and *foldmap*. At this moment, cats comes only with
  -*foldm*.
  -
  -The *foldm* function in analgous to the `foldl` in terms of how it does the fold operation,
  -with the difference that is aware of the monad context. Or in other terms, it works with
  -reducing function that return monad types.
  -
  -Let see an example:
  -
  -[source, clojure]
  -----
  -(defn m-div
  -  [x y]
  -  (if (zero? y)
  -    (maybe/nothing)
  -    (maybe/just (/ x y))))
  -
  -(m/foldm m-div 1 [1 2 3])
  -;; => #<Just 1/6>
  -
  -
  -(m/foldm m-div 1 [1 0 3])
  -;; => #<Nothing>
  -----
  -
  -=== Traversable
  -
  -The *Traversable* is a generic abstraction for data structures that can be traversed from
  -left to right, running an Applicative action for each element. Traversables must also be
  -Functors and Foldables.
  -
  -Note that, since Traversables use the Applicative's `pure` operation, the context of the
  -applicative must be set when using the `traverse` function.
  -
  -Let's look at an example: we have a vector with numbers that we want to map to a Maybe value,
  -and we want to aggregate the result in a Maybe. If any of the actions fails (is Nothing) the
  -resulting aggregate will be Nothing, but if all succeed we preserve the vector's structure
  -inside a Just value.
  -
  -First of all, we define the function that will transform a number to a Maybe. Our function will
  -wrap the value in a Just if it's even and in a Nothing if it's not:
  -
  -[source, clojure]
  -----
  -(require '[cats.monad.maybe :as maybe])
  -
  -(defn just-if-even
  -  [n]
  -  (if (even? n)
  -    (maybe/just n)
  -    (maybe/nothing)))
  -----
  -
  -Now that we have a function that maps a value to the Maybe Applicative, we can traverse a vector
  -of numbers and aggregate a Maybe value. The applicatives will be evaluated from left to right using
  -the applicative's `fapply`.
  -
  -[source, clojure]
  -----
  -(require '[cats.core :as m])
  -(require '[cats.context :as ctx])
  -
  -(ctx/with-context maybe/context
  -  (m/traverse just-if-even []))
  -;; => #<Just []>
  -
  -(ctx/with-context maybe/context
  -  (m/traverse just-if-even [2 4]))
  -;; => #<Just [2 4]>
  -
  -(ctx/with-context maybe/context
  -  (m/traverse just-if-even [1 2]))
  -;; => #<Nothing >
  -
  -(ctx/with-context maybe/context
  -  (m/traverse just-if-even [2 3]))
  -;; => #<Nothing >
  -----
  -
  -Maybe is not that much of an interesting applicative, let's see an example of using the Validation
  -applicative to validate a vector of values aggregating the results, be them success or failure.
  -
  -First we will define a validation function that, given a number, will succed if it's even. If it's
  -odd, it will fail and record the failure in the map monoid from value to the error type (`:not-even`).
  -
  -[source, clojure]
  -----
  -(require '[cats.applicative.validation :as v])
  -
  -(defn valid-if-even
  -  [n]
  -  (if (even? n)
  -    (v/ok n)
  -    (v/fail {n :not-even})))
  -----
  -
  -Now let's try it with some vectors to see how failures are aggregated:
  -
  -[source, clojure]
  -----
  -(require '[cats.core :as m])
  -(require '[cats.context :as ctx])
  -
  -(ctx/with-context v/context
  -  (m/traverse valid-if-even []))
  -;; => #<Ok []>
  -
  -(ctx/with-context v/context
  -  (m/traverse valid-if-even [2 4]))
  -;; => #<Ok [2 4]>
  -
  -(ctx/with-context v/context
  -  (m/traverse valid-if-even [1 2]))
  -;; => #<Fail {1 :not-even}>
  -
  -(ctx/with-context v/context
  -  (m/traverse valid-if-even [2 3 4 5]))
  -;; => #<Fail {3 :not-even, 5 :not-even}>
  -----
  -
  -
  -=== Monad
  -
  -Monads are the most discussed programming concept to come from category theory. Like functors and
  -applicatives, monads deal with data in contexts.
  -
  -Additionally, monads can also transform contexts by unwrapping data, applying functions to it and
  -putting new values in a completely different context.
  -
  -The monad abstraction consists of two functions: *bind* and *return*
  -
  -.Bind function signature.
  -[source,clojure]
  -----
  -(bind [mv f])
  -----
  -
  -As you can see, bind works much like a Functor but with inverted arguments. The main difference is
  -that in a monad, the function is responsible for wrapping a returned value in a context.
  -
  -.Example usage of the bind higher-order function.
  -[source,clojure]
  -----
  -(m/bind (maybe/just 1)
  -        (fn [v] (maybe/just (inc v))))
  -;; => #<Just 2>
  -----
  -
  -One of the key features of the bind function is that any computation executed within the context of
  -bind (monad) knows the context type implicitly. With this, if you apply some computation over some
  -monadic value and you want to return the result in the same container context but don't know
  -what that container is, you can use `return` or `pure` functions:
  -
  -.Usage of return function in bind context.
  -[source,clojure]
  -----
  -(m/bind (maybe/just 1)
  -        (fn [v]
  -          (m/return (inc v))))
  -;; => #<Just 2>
  -----
  -
  -The `return` or `pure` functions, when called with one argument, try to use the dynamic scope context
  -value that's set internally by the `bind` function. Therefore, you can't use them with one argument outside of a `bind` context.
  -
  -We now can compose any number of computations using monad *bind*
  -functions. But observe what happens when the number of computations increases:
  -
  -.Composability example of bind function.
  -[source, clojure]
  -----
  -(m/bind (maybe/just 1)
  -        (fn [a]
  -          (m/bind (maybe/just (inc a))
  -                  (fn [b]
  -                    (m/return (* b 2))))))
  -----
  -
  -This can quickly lead to callback hell. To solve this, _cats_ comes with a powerful
  -macro: *mlet*
  -
  -.Previous example but using *mlet* macro.
  -[source, clojure]
  -----
  -(m/mlet [a (maybe/just 1)
  -         b (maybe/just (inc a))]
  -  (m/return (* b 2)))
  -----
  -
  -NOTE: If you are coming from Haskell, mlet represents the *do-syntax*.
  -
  -
  -If you want to use regular (non-monadic) let bindings inside an `mlet` block, you can do so using
  -`:let` and a binding vector inside the mlet bindings:
  -
  -[source, clojure]
  -----
  -(m/mlet [a (maybe/just 1)
  -         b (maybe/just (inc a))
  -         :let [z (+ a b)]]
  -  (m/return (* z 2)))
  -----
  -
  -
  -=== MonadZero
  -
  -Some monads also have the notion of an identity element analogous to that of Monoid. When calling `bind` on a identity element
  -for a monad, the same value is returned. This means that whenever we encounter the identity element in a monadic composition it will
  -short-circuit.
  -
  -For the already familiar Maybe type the identity element is Nothing:
  -
  -[source, clojure]
  -----
  -(require '[cats.core :as m])
  -(require '[cats.monad.maybe :as maybe])
  -
  -(m/mzero maybe/maybe-monad)
  -;; => #<Nothing >
  -----
  -
  -Having an identity element we can make a monadic composition short-circuit using a predicate:
  -
  -[source, clojure]
  -----
  -(require '[cats.core :as m])
  -(require '[cats.monad.maybe :as maybe])
  -
  -(m/bind (maybe/just 1)
  -        (fn [a]
  -          (m/bind (if (= a 2)
  -                    (m/return nil)
  -                    (m/mzero))
  -                  (fn [_]
  -                    (m/return (* a 2))))))
  -;; => #<Nothing >
  -----
  -
  -As you can see in the above example the predicate `(= a 2)` returns either a monadic value `(m/return nil)` or the identity value
  -for the maybe monad. This can be captured in a function, which is available in `cats.core` namespace:
  -
  -[source, clojure]
  -----
  -(defn guard
  -  [b]
  -  (if b
  -    (return nil)
  -    (mzero)))
  -----
  -
  -The above example could be rewritten as:
  -
  -[source, clojure]
  -----
  -(require '[cats.core :as m])
  -(require '[cats.monad.maybe :as maybe])
  -
  -(m/bind (maybe/just 1)
  -        (fn [a]
  -          (m/bind (m/guard (= a 2))
  -                  (fn [_]
  -                    (m/return (* a 2))))))
  -;; => #<Nothing >
  -----
  -
  -`mlet` has support for using guards using a `:when` clause, analogous to the one used in `for`. We could rewrite the above example
  -using `bind` with `mlet` and `:when`:
  -
  -[source, clojure]
  -----
  -(require '[cats.core :as m])
  -(require '[cats.monad.maybe :as maybe])
  -
  -(m/mlet [a (maybe/just 1)
  -         :when (= a 2)]
  -   (m/return (* a 2)))
  -;; => #<Nothing >
  -----
  -
  -Any monadic type that implements `MonadZero` can be combined with guards inside `mlet` bindings.
  -
  -=== MonadPlus
  -
  -MonadPlus is a complementary abstraction for Monads that support an associative binary operation, analogous to that of a
  -Semigroup. If the monad implements the MonadZero and MonadPlus protocols it forms a monoid.
  -
  -For the Maybe type, `mplus` acts similarly to a logical OR that treats `Nothing` values as falsey.
  -
  -[source, clojure]
  -----
  -(require '[cats.core :as m])
  -(require '[cats.monad.maybe :as maybe])
  -
  -(m/mplus (maybe/nothing))
  -;; => #<Nothing >
  -
  -(m/mplus (maybe/nothing) (maybe/just 1))
  -;; => #<Just 1>
  -
  -(m/mplus (maybe/just 1) (maybe/just 2))
  -;; => #<Just 1>
  -----
  -
  -
  -=== Monad Transformers
  -
  -==== Motivation
  -
  -We can combine two functors and get a new one automatically. Given any two functors _a_ and _b_,
  -we can implement a generic `fmap` for the type _a (b Any)_, we'll call it fmap2:
  -
  -[source, clojure]
  -----
  -(ns functor.example
  -  (:require [cats.core :refer [fmap]]
  -            [cats.builtin]
  -            [cats.monad.maybe :refer [just]]))
  -
  -(defn fmap2
  -  [f fv]
  -  (fmap (partial fmap f) fv))
  -
  -; Here, 'a' is [] and 'b' is Maybe, so the type of the
  -; combined functor is a vector of Maybe values that could
  -; contain a value of any type.
  -(fmap2 inc [(maybe/just 1) (maybe/just 2)])
  -;; => [#<Just 2> #<Just 3>]
  -----
  -
  -However, monads don't compose as nicely as functors do. We have to actually implement
  -the composition ourselves.
  -
  -In some circumstances we would like combine the effects of two monads into another one. We call the
  -resulting monad a monad transformer, which is the composition of a "base" and "inner" monad. A
  -monad transformer is itself a monad.
  -
  -
  -==== Using monad transformers
  -
  -Let's combine the effects of two monads: State and Maybe. We'll create the transformer
  -using State as the base monad since we want the resulting type to be a stateful computation
  -that may fail: `s -> Maybe (a, s)`.
  -
  -Almost every monad implemented in _cats_ has a monad transformer for combining it with
  -any other monad. The transformer functions take a Monad as their argument and they
  -return a reified MonadTrans:
  -
  -[source, clojure]
  -----
  -(ns transformers.example
  -  (:require [cats.core :as m]
  -            [cats.data :as data]
  -            [cats.monad.maybe :as maybe]
  -            [cats.labs.state :as state]))
  -
  -(def maybe-state
  -  (state/state-transformer maybe/maybe-monad))
  -
  -(m/with-monad maybe-state
  -  (state/run-state (m/return 42) {}))
  -;; => #<Just #<Pair [42 {}]>>
  -----
  -
  -As we can see in the example below, the return of the `maybe-state` monad creates a stateful
  -function that yields a Maybe containing a pair (value, next state).
  -
  -You probably noticed that we had to wrap the state function invocation with `cats.core/with-monad`.
  -When working with monad transformers, we have to be explicit about what monad we are using to implement
  -the binding policy since there is no way to distinguish values from a transformer type from those of
  -a regular monad.
  -
  -The `maybe-state` monad combines the semantics of both State and Maybe.
  -
  -
  -== Types
  -
  -=== Maybe
  -
  -This is one of the two most used monad types (also known as Optional in other programming
  -languages).
  -
  -The Maybe monad represents encapsulation of an optional value; e.g. it is used as the return type
  -of functions which may or may not return a meaningful value when they are applied. It consists
  -of either an empty constructor (called None or Nothing), or a constructor
  -encapsulating the original data type A (e.g. Just A or Some A).
  -
  -_cats_, implements two types:
  -
  -- `Just` that represents a value in a context.
  -- `Nothing` that represents the abscense of value.
  -
  -.Example creating instances of `Just` and `Nothing` types:
  -[source, clojure]
  -----
  -(maybe/just 1)
  -;; => #<Just 1>
  -
  -(maybe/nothing)
  -;; => #<Nothing >
  -----
  -
  -There are other useful functions for working with maybe monad types in the same namespace.
  -See the API documentation for a full list of them. But here we will explain a little relevant subset
  -of them.
  -
  -We mentioned above that *fmap* extracts the value from a functor context. You will also want to
  -extract values wrapped by *just* and you can do that with *from-maybe*.
  -
  -As we said previously, the Just or Nothing instances act like wrappers and in some circumstances
  -you will want extract the plain value from them. cats offers the `from-maybe` function for that.
  -
  -.Example using *from-maybe* to extract values wrapped by *just*.
  -[source, clojure]
  -----
  -(maybe/from-maybe (maybe/just 1))
  -;; => 1
  -
  -(maybe/from-maybe (maybe/nothing))
  -;; => nil
  -
  -(maybe/from-maybe (maybe/nothing) 42)
  -;; => 42
  -----
  -
  -The `from-maybe` function is a specialized version of a more generic one: `cats.core/extract`.
  -The generic version is a polymorphic function and will also work with different
  -types of different monads.
  -
  -For interoperability with Clojure and ClojureScript's `IDeref` abstraction, maybe values are
  -derrefable.
  -
  -.Example using *deref* to extract values wrapped by *just*.
  -[source, clojure]
  -----
  -(deref (maybe/just 1))
  -;; => 1
  -
  -(deref (maybe/nothing))
  -;; => nil
  -----
  -
  -=== Either
  -
  -Either is another type that represents a result of a computation, but (in contrast with maybe)
  -it can return some data with a failed computation result.
  -
  -In _cats_ it has two constructors:
  -
  -- `(left v)`: represents a failure.
  -- `(right v)`: represents a successful result.
  -
  -.Usage example of *Either* constructors.
  -[source, clojure]
  -----
  -(require '[cats.monad.either :refer :all])
  -
  -(right :valid-value)
  -;; => #<Right [:valid-value :right]>
  -
  -(left "Error message")
  -;; => #<Either [Error message :left]>
  -----
  -
  -NOTE: Either is also (like Maybe) a Functor, Applicative Functor and Monad.
  -
  -Like Maybe, Either values can be dereferenced returning the value they contain.
  -
  -
  -=== Exception
  -
  -Also known as the Try monad, as popularized by Scala.
  -
  -It represents a computation that may either result in an exception or return a successfully computed
  -value. Is very similar to the Either monad, but is semantically different.
  -
  -It consists of two types: Success and Failure. The Success type is a simple
  -wrapper, like Right of the Either monad. But the Failure type is slightly different
  -from Left, because it always wraps an instance of Throwable (or any value in cljs since you can
  -throw arbitrary values in the JavaScript host).
  -
  -The most common use case of this monad is to wrap third party libraries that use standard Exception
  -based error handling. Under normal circumstances, however, you should use Either instead.
  -
  -It is an analogue of the try-catch block: it replaces try-catch's stack-based error handling with
  -heap-based error handling. Instead of having an exception thrown and having to deal with it immediately
  -in the same thread, it disconnects the error handling and recovery.
  -
  -.Usage example of *try-on* macro.
  -[source, clojure]
  -----
  -(require '[cats.monad.exception :as exc])
  -
  -(exc/try-on 1)
  -;; => #<Success [1]>
  -
  -(exc/try-on (+ 1 nil))
  -;; => #<Failure [#<NullPointerException java.lang.NullPointerException>]>
  -----
  -
  -_cats_ comes with other syntactic sugar macros: `try-or-else` that returns a default value if a
  -computation fails, and `try-or-recover` that lets you handle the return value when executing a
  -function with the exception as first parameter.
  -
  -.Usage example of `try-or-else` macro.
  -[source, clojure]
  -----
  -(exc/try-or-else (+ 1 nil) 2)
  -;; => #<Success [2]>
  -----
  -
  -.Usage example of `try-or-recover` macro.
  -[source, clojure]
  -----
  -(exc/try-or-recover (+ 1 nil)
  -                    (fn [e]
  -                      (cond
  -                        (instance? NullPointerException e) 0
  -                        :else 100)))
  -;; => #<Success [0]>
  -----
  -
  -The types defined for the Exception monad (Success and Failure) also implement the Clojure IDeref
  -interface, which allows library development using monadic composition without forcing a user of
  -that library to use or understand monads.
  -
  -That is because when you dereference the failure instance, it will reraise the
  -enclosed exception.
  -
  -.Example dereferencing a failure instance
  -[source, clojure]
  -----
  -(def f (exc/try-on (+ 1 nil)))
  -
  -@f
  -;; => NullPointerException   clojure.lang.Numbers.ops (Numbers.java:961)
  -----
  -
  -
  -=== Validation
  -
  -The validation type is similar to the Either or Exception types except that it
  -doesn't implement a Monad instance. It has two constructors: `ok` and `fail`,
  -representing success and failure respectively.
  -
  -[source, clojure]
  -----
  -(require '[cats.applicative.validation :as v])
  -(require '[cats.core :as m])
  -
  -(v/ok 42)
  -;; => #<Ok 42>
  -
  -(v/fail [])
  -;; => #<Fail []>
  -----
  -
  -It implements the Applicative protocol, and its intended usage is as an Applicative. Applying Validation
  -values together errs on the side of the failure, and applying failures together aggregates their values
  -using the Semigroup's `mappend` function.
  -
  -[source, clojure]
  -----
  -(require '[cats.applicative.validation :as v])
  -(require '[cats.core :as m])
  -
  -(m/fapply (v/ok 42) (v/fail "OH NOES"))
  -;; => #<Fail "OH NOES">
  -
  -;; Note that `<*>` is a variadic fapply
  -(m/<*> (v/ok 42)
  -       (v/fail {:foo "bar"})
  -       (v/fail {:baz "fubar"})
  -       (v/ok 99))
  -;; => #<Fail {:baz "fubar", :foo "bar"}>
  -----
  -
  -
  -=== Built in types
  -
  -Some of the abstractions in _cats_ are implemented for built-in types but you can't use them directly. First,
  -you must load the `cats.builtin` namespace:
  -
  -[source, clojure]
  -----
  -(use 'cats.builtin)
  -(require '[cats.core :as m])
  -
  -(m/fmap inc [1 2 3 4])
  -;; => [2 3 4 5]
  -----
  -
  -
  -==== nil
  -
  -Given the fact that `nil` is both a value and a type, we have extended the `nil` type to be equivalent
  -to Maybe monad's `Nothing`. This means that you can use `nil` as if were a `Just` instance like in the
  -following example:
  -
  -[source, clojure]
  -----
  -(use 'cats.builtin)
  -(require '[cats.core :as m])
  -(require '[cats.monad.maybe :as maybe])
  -
  -(m/mlet [x (maybe/just 42)
  -         y nil]
  -  (m/return (+ x y)))
  -;; => nil
  -----
  -
  -As you can see, the `mlet` short-circuits when encountering a `nil` value.
  -
  -
  -==== Vector
  -
  -Clojure vectors also participate in several of the abstractions implemented in _cats_, most notably
  -as a monad. Compare the following `for` comprehension:
  -
  -[source, clojure]
  -----
  -(for [x [1 2]
  -      y [3 4 5]]
  -   (+ x y))
  -;; => (4 5 6 5 6 7)
  -----
  -
  -with the equivalent using _mlet_:
  -
  -[source, clojure]
  -----
  -(use 'cats.builtin)
  -(require '[cats.core :as m])
  -
  -(m/mlet [x [1 2]
  -         y [3 4 5]]
  -  (m/return (+ x y)))
  -;; => [4 5 6 5 6 7]
  -----
  -
  -Note the symmetry between `for` and `mlet`. This is not accidental, both are what is called a monad comprehension,
  -the difference is that `for` is limited to sequences and `mlet` can work with arbitrary monads.
  -
  -Also, since `mlet` desugars into calls to the Monad's `bind` function, its result keeps the type of the monadic values.
  -
  -
  -==== Lazy sequences
  -
  -Lazy sequences implement the same abstractions as vectors with practically an identical implementation. If you don't need
  -the results right away or are interested in a subset of the final results, you can use lazy sequence comprehensions.
  -
  -Using `mlet` with lazy sequences yields exactly the same result as using `for`:
  -
  -[source, clojure]
  -----
  -(use 'cats.builtin)
  -(require '[cats.core :as m])
  -
  -(m/mlet [x (lazy-seq [1 2])
  -         y (lazy-seq [3 4 5])]
  -  (m/return (+ x y)))
  -;; => (4 5 6 5 6 7)
  -----
  -
  -
  -==== Set
  -
  -Sets implement almost every abstraction in _cats_, from Semigroup to Monad.
  -
  -[source, clojure]
  -----
  -(use 'cats.builtin)
  -(require '[cats.core :as m])
  -
  -(m/pure set-monad 42)
  -;; => #{42}
  -
  -(m/fmap inc #{1 2 3 4})
  -;; => #{4 3 2 5}
  -
  -(m/bind #{1 2 3}
  -        (fn [v] #{v (inc v)}))
  -;; => #{1 4 3 2}
  -----
  -
  -
  -==== Map
  -
  -Maps implement the _Semigroup_ protocol, since we can use `merge` as their associative binary operation. Using
  -`mappend` on maps is a way to merge them together:
  -
  -[source, clojure]
  -----
  -(use 'cats.builtin)
  -(require '[cats.core :as m])
  -
  -(m/mappend {:a "A"} {:b "B"})
  -;; => {:a "A", :b "B"}
  -----
  -
  -Since we can consider the empty map an identity element for the `mappend` associative binary operation maps also
  -implement _Monoid_ and the `mempty` function gives an empty map.
  -
  -
  -=== Complementary libraries
  -
  -Some monads are defined as separated package to avoid additional
  -and unnecesary dependencies to cats. Also, there are some libraries
  -that build higher-level abstractions on top of what cats offers.
  -
  -* Promise monad (ClojureScript): https://github.com/funcool/promesa
  -* Promise monad (Clojure): https://github.com/funcool/promissum
  -* Concurrent data fetching: https://github.com/kachayev/muse
  -
   
   == Higher-order functions
   
  
positive.code: 
  TODO
  
  
  == FAQ
  
  
negative.code: ;; => #<Just 5>
  ----
  
  If you do not understand the purpose of the *pure* function, the next sections
  should clarify its purpose.
  
  
  === Foldable
  
  The *Foldable* is a generic abstraction for data structures that can be folded. It consists
  mainly on two functions: `foldl` and `foldr`. `foldl` is also known as `reduce` or `inject`
  in other mainstream programming languages.
  
  Both function have an identical signature and differ in how they traverse the data structure.
  Let's look at a little example using `foldl`:
  
  [source, clojure]
  ----
  (foldl (fn [acc v] (+ acc v)) 0 [1 2 3 4 5])
  ;; => 15
  ----
  
  You can observe that `foldl` is identical to the clojure `reduce` function:
  
  [source, clojure]
  ----
  (reduce (fn [acc v] (+ acc v)) 0 [1 2 3 4 5])
  ;; => 15
  ----
  
  And the same operation can be done using `foldr`:
  
  [source, clojure]
  ----
  (foldr (fn [v wc] (+ v wc)) 0 [1 2 3 4 5])
  ;; => 15
  ----
  
  The main difference between `foldl` and `reduce` is that `foldl` has a fixed arity so all
  parameters are mandatory and `foldl` is a generic abstraction that can work with other
  types apart from collections.
  
  As we said previously, the `foldl` and `foldr` differ mainly on how they traverse the
  data structure. Then, for understanding better how they work internally, let's see a
  graphical representation of the `foldl` execution model:
  
  [source, text]
  ----
  ((((acc⊕1)⊕2)⊕3)⊕4)⊕5
  ----
  
  In contrast to the `foldr` internal execution model:
  
  [source, text]
  ----
  1⊕(2⊕(3⊕(4⊕(5⊕(wc)))))
  ----
  
  In languages with strict argument evaluation, `foldr` does not have many
  applications because when the data structure to fold grows it tends to consume all the
  stack (causing the well known stack overflow). In case of Clojure, the unique obvious
  case of using foldr is for small datastructures.
  
  [source, clojure]
  ----
  (m/foldr #(cons (inc %1) %2) '() (range 100000))
  ;; => StackOverflowError
  ----
  
  The *Foldable* abstraction is already implemented for cloure vectors, lazy seqs and ranges
  plus the cats maybe, either and validation types. Let see an example how it behaves with maybe:
  
  [source, clojure]
  ----
  (m/foldl #(m/return (+ %1 %2)) 1 (maybe/just 1))
  ;; => #<Just 1>
  
  (m/foldl #(m/return (+ %1 %2)) 1 (maybe/nothing))
  ;; => 1
  ----
  
  It there also other fold functions that are implemented in terms of the basic `foldl`
  or `foldr` that can be *foldm* and *foldmap*. At this moment, cats comes only with
  *foldm*.
  
  The *foldm* function in analgous to the `foldl` in terms of how it does the fold operation,
  with the difference that is aware of the monad context. Or in other terms, it works with
  reducing function that return monad types.
  
  Let see an example:
  
  [source, clojure]
  ----
  (defn m-div
    [x y]
    (if (zero? y)
      (maybe/nothing)
      (maybe/just (/ x y))))
  
  (m/foldm m-div 1 [1 2 3])
  ;; => #<Just 1/6>
  
  
  (m/foldm m-div 1 [1 0 3])
  ;; => #<Nothing>
  ----
  
  === Traversable
  
  The *Traversable* is a generic abstraction for data structures that can be traversed from
  left to right, running an Applicative action for each element. Traversables must also be
  Functors and Foldables.
  
  Note that, since Traversables use the Applicative's `pure` operation, the context of the
  applicative must be set when using the `traverse` function.
  
  Let's look at an example: we have a vector with numbers that we want to map to a Maybe value,
  and we want to aggregate the result in a Maybe. If any of the actions fails (is Nothing) the
  resulting aggregate will be Nothing, but if all succeed we preserve the vector's structure
  inside a Just value.
  
  First of all, we define the function that will transform a number to a Maybe. Our function will
  wrap the value in a Just if it's even and in a Nothing if it's not:
  
  [source, clojure]
  ----
  (require '[cats.monad.maybe :as maybe])
  
  (defn just-if-even
    [n]
    (if (even? n)
      (maybe/just n)
      (maybe/nothing)))
  ----
  
  Now that we have a function that maps a value to the Maybe Applicative, we can traverse a vector
  of numbers and aggregate a Maybe value. The applicatives will be evaluated from left to right using
  the applicative's `fapply`.
  
  [source, clojure]
  ----
  (require '[cats.core :as m])
  (require '[cats.context :as ctx])
  
  (ctx/with-context maybe/context
    (m/traverse just-if-even []))
  ;; => #<Just []>
  
  (ctx/with-context maybe/context
    (m/traverse just-if-even [2 4]))
  ;; => #<Just [2 4]>
  
  (ctx/with-context maybe/context
    (m/traverse just-if-even [1 2]))
  ;; => #<Nothing >
  
  (ctx/with-context maybe/context
    (m/traverse just-if-even [2 3]))
  ;; => #<Nothing >
  ----
  
  Maybe is not that much of an interesting applicative, let's see an example of using the Validation
  applicative to validate a vector of values aggregating the results, be them success or failure.
  
  First we will define a validation function that, given a number, will succed if it's even. If it's
  odd, it will fail and record the failure in the map monoid from value to the error type (`:not-even`).
  
  [source, clojure]
  ----
  (require '[cats.applicative.validation :as v])
  
  (defn valid-if-even
    [n]
    (if (even? n)
      (v/ok n)
      (v/fail {n :not-even})))
  ----
  
  Now let's try it with some vectors to see how failures are aggregated:
  
  [source, clojure]
  ----
  (require '[cats.core :as m])
  (require '[cats.context :as ctx])
  
  (ctx/with-context v/context
    (m/traverse valid-if-even []))
  ;; => #<Ok []>
  
  (ctx/with-context v/context
    (m/traverse valid-if-even [2 4]))
  ;; => #<Ok [2 4]>
  
  (ctx/with-context v/context
    (m/traverse valid-if-even [1 2]))
  ;; => #<Fail {1 :not-even}>
  
  (ctx/with-context v/context
    (m/traverse valid-if-even [2 3 4 5]))
  ;; => #<Fail {3 :not-even, 5 :not-even}>
  ----
  
  
  === Monad
  
  Monads are the most discussed programming concept to come from category theory. Like functors and
  applicatives, monads deal with data in contexts.
  
  Additionally, monads can also transform contexts by unwrapping data, applying functions to it and
  putting new values in a completely different context.
  
  The monad abstraction consists of two functions: *bind* and *return*
  
  .Bind function signature.
  [source,clojure]
  ----
  (bind [mv f])
  ----
  
  As you can see, bind works much like a Functor but with inverted arguments. The main difference is
  that in a monad, the function is responsible for wrapping a returned value in a context.
  
  .Example usage of the bind higher-order function.
  [source,clojure]
  ----
  (m/bind (maybe/just 1)
          (fn [v] (maybe/just (inc v))))
  ;; => #<Just 2>
  ----
  
  One of the key features of the bind function is that any computation executed within the context of
  bind (monad) knows the context type implicitly. With this, if you apply some computation over some
  monadic value and you want to return the result in the same container context but don't know
  what that container is, you can use `return` or `pure` functions:
  
  .Usage of return function in bind context.
  [source,clojure]
  ----
  (m/bind (maybe/just 1)
          (fn [v]
            (m/return (inc v))))
  ;; => #<Just 2>
  ----
  
  The `return` or `pure` functions, when called with one argument, try to use the dynamic scope context
  value that's set internally by the `bind` function. Therefore, you can't use them with one argument outside of a `bind` context.
  
  We now can compose any number of computations using monad *bind*
  functions. But observe what happens when the number of computations increases:
  
  .Composability example of bind function.
  [source, clojure]
  ----
  (m/bind (maybe/just 1)
          (fn [a]
            (m/bind (maybe/just (inc a))
                    (fn [b]
                      (m/return (* b 2))))))
  ----
  
  This can quickly lead to callback hell. To solve this, _cats_ comes with a powerful
  macro: *mlet*
  
  .Previous example but using *mlet* macro.
  [source, clojure]
  ----
  (m/mlet [a (maybe/just 1)
           b (maybe/just (inc a))]
    (m/return (* b 2)))
  ----
  
  
  === MonadZero
  
  Some monads also have the notion of an identity element analogous to that of Monoid. When calling `bind` on a identity element
  for a monad, the same value is returned. This means that whenever we encounter the identity element in a monadic composition it will
  short-circuit.
  
  For the already familiar Maybe type the identity element is Nothing:
  
  [source, clojure]
  ----
  (require '[cats.core :as m])
  (require '[cats.monad.maybe :as maybe])
  
  (m/mzero maybe/maybe-monad)
  ;; => #<Nothing >
  ----
  
  Having an identity element we can make a monadic composition short-circuit using a predicate:
  
  [source, clojure]
  ----
  (require '[cats.core :as m])
  (require '[cats.monad.maybe :as maybe])
  
  (m/bind (maybe/just 1)
          (fn [a]
            (m/bind (if (= a 2)
                      (m/return nil)
                      (m/mzero))
                    (fn [_]
                      (m/return (* a 2))))))
  ;; => #<Nothing >
  ----
  
  As you can see in the above example the predicate `(= a 2)` returns either a monadic value `(m/return nil)` or the identity value
  for the maybe monad. This can be captured in a function, which is available in `cats.core` namespace:
  
  [source, clojure]
  ----
  (defn guard
    [b]
    (if b
      (return nil)
      (mzero)))
  ----
  
  The above example could be rewritten as:
  
  [source, clojure]
  ----
  (require '[cats.core :as m])
  (require '[cats.monad.maybe :as maybe])
  
  (m/bind (maybe/just 1)
          (fn [a]
            (m/bind (m/guard (= a 2))
                    (fn [_]
                      (m/return (* a 2))))))
  ;; => #<Nothing >
  ----
  
  Or, using mlet:
  
  
  [source, clojure]
  ----
  (require '[cats.core :as m])
  (require '[cats.monad.maybe :as maybe])
  
  (m/mlet [a (maybe/just 1)
           :when (= a 2)]
     (m/return (* a 2)))
  ;; => #<Nothing >
  ----
  
  === MonadPlus
  
  MonadPlus is a complementary abstraction for Monads that support an associative binary operation, analogous to that of a
  Semigroup. If the monad implements the MonadZero and MonadPlus protocols it forms a monoid.
  
  For the Maybe type, `mplus` acts similarly to a logical OR that treats `Nothing` values as falsey.
  
  [source, clojure]
  ----
  (require '[cats.core :as m])
  (require '[cats.monad.maybe :as maybe])
  
  (m/mplus (maybe/nothing))
  ;; => #<Nothing >
  
  (m/mplus (maybe/nothing) (maybe/just 1))
  ;; => #<Just 1>
  
  (m/mplus (maybe/just 1) (maybe/just 2))
  ;; => #<Just 1>
  ----
  
  
  === Monad Transformers
  
  ==== Motivation
  
  We can combine two functors and get a new one automatically. Given any two functors _a_ and _b_,
  we can implement a generic `fmap` for the type _a (b Any)_, we'll call it fmap2:
  
  [source, clojure]
  ----
  (ns functor.example
    (:require [cats.core :refer [fmap]]
              [cats.builtin]
              [cats.monad.maybe :refer [just]]))
  
  (defn fmap2
    [f fv]
    (fmap (partial fmap f) fv))
  
  ; Here, 'a' is [] and 'b' is Maybe, so the type of the
  ; combined functor is a vector of Maybe values that could
  ; contain a value of any type.
  (fmap2 inc [(maybe/just 1) (maybe/just 2)])
  ;; => [#<Just 2> #<Just 3>]
  ----
  
  However, monads don't compose as nicely as functors do. We have to actually implement
  the composition ourselves.
  
  In some circumstances we would like combine the effects of two monads into another one. We call the
  resulting monad a monad transformer, which is the composition of a "base" and "inner" monad. A
  monad transformer is itself a monad.
  
  
  ==== Using monad transformers
  
  Let's combine the effects of two monads: State and Maybe. We'll create the transformer
  using State as the base monad since we want the resulting type to be a stateful computation
  that may fail: `s -> Maybe (a, s)`.
  
  Almost every monad implemented in _cats_ has a monad transformer for combining it with
  any other monad. The transformer functions take a Monad as their argument and they
  return a reified MonadTrans:
  
  [source, clojure]
  ----
  (ns transformers.example
    (:require [cats.core :as m]
              [cats.data :as data]
              [cats.monad.maybe :as maybe]
              [cats.labs.state :as state]))
  
  (def maybe-state
    (state/state-transformer maybe/maybe-monad))
  
  (m/with-monad maybe-state
    (state/run-state (m/return 42) {}))
  ;; => #<Just #<Pair [42 {}]>>
  ----
  
  As we can see in the example below, the return of the `maybe-state` monad creates a stateful
  function that yields a Maybe containing a pair (value, next state).
  
  You probably noticed that we had to wrap the state function invocation with `cats.core/with-monad`.
  When working with monad transformers, we have to be explicit about what monad we are using to implement
  the binding policy since there is no way to distinguish values from a transformer type from those of
  a regular monad.
  
  The `maybe-state` monad combines the semantics of both State and Maybe.
  
  
  == Types
  
  === Maybe
  
  This is one of the two most used monad types (also known as Optional in other programming
  languages).
  
  The Maybe monad represents encapsulation of an optional value; e.g. it is used as the return type
  of functions which may or may not return a meaningful value when they are applied. It consists
  of either an empty constructor (called None or Nothing), or a constructor
  encapsulating the original data type A (e.g. Just A or Some A).
  
  _cats_, implements two types:
  
  - `Just` that represents a value in a context.
  - `Nothing` that represents the abscense of value.
  
  .Example creating instances of `Just` and `Nothing` types:
  [source, clojure]
  ----
  (maybe/just 1)
  ;; => #<Just 1>
  
  (maybe/nothing)
  ;; => #<Nothing >
  ----
  
  There are other useful functions for working with maybe monad types in the same namespace.
  See the API documentation for a full list of them. But here we will explain a little relevant subset
  of them.
  
  We mentioned above that *fmap* extracts the value from a functor context. You will also want to
  extract values wrapped by *just* and you can do that with *from-maybe*.
  
  As we said previously, the Just or Nothing instances act like wrappers and in some circumstances
  you will want extract the plain value from them. cats offers the `from-maybe` function for that.
  
  .Example using *from-maybe* to extract values wrapped by *just*.
  [source, clojure]
  ----
  (maybe/from-maybe (maybe/just 1))
  ;; => 1
  
  (maybe/from-maybe (maybe/nothing))
  ;; => nil
  
  (maybe/from-maybe (maybe/nothing) 42)
  ;; => 42
  ----
  
  The `from-maybe` function is a specialized version of a more generic one: `cats.core/extract`.
  The generic version is a polymorphic function and will also work with different
  types of different monads.
  
  For interoperability with Clojure and ClojureScript's `IDeref` abstraction, maybe values are
  derrefable.
  
  .Example using *deref* to extract values wrapped by *just*.
  [source, clojure]
  ----
  (deref (maybe/just 1))
  ;; => 1
  
  (deref (maybe/nothing))
  ;; => nil
  ----
  
  === Either
  
  Either is another type that represents a result of a computation, but (in contrast with maybe)
  it can return some data with a failed computation result.
  
  In _cats_ it has two constructors:
  
  - `(left v)`: represents a failure.
  - `(right v)`: represents a successful result.
  
  .Usage example of *Either* constructors.
  [source, clojure]
  ----
  (require '[cats.monad.either :refer :all])
  
  (right :valid-value)
  ;; => #<Right [:valid-value :right]>
  
  (left "Error message")
  ;; => #<Either [Error message :left]>
  ----
  
  NOTE: Either is also (like Maybe) a Functor, Applicative Functor and Monad.
  
  Like Maybe, Either values can be dereferenced returning the value they contain.
  
  
  === Exception
  
  Also known as the Try monad, as popularized by Scala.
  
  It represents a computation that may either result in an exception or return a successfully computed
  value. Is very similar to the Either monad, but is semantically different.
  
  It consists of two types: Success and Failure. The Success type is a simple
  wrapper, like Right of the Either monad. But the Failure type is slightly different
  from Left, because it always wraps an instance of Throwable (or any value in cljs since you can
  throw arbitrary values in the JavaScript host).
  
  The most common use case of this monad is to wrap third party libraries that use standard Exception
  based error handling. Under normal circumstances, however, you should use Either instead.
  
  It is an analogue of the try-catch block: it replaces try-catch's stack-based error handling with
  heap-based error handling. Instead of having an exception thrown and having to deal with it immediately
  in the same thread, it disconnects the error handling and recovery.
  
  .Usage example of *try-on* macro.
  [source, clojure]
  ----
  (require '[cats.monad.exception :as exc])
  
  (exc/try-on 1)
  ;; => #<Success [1]>
  
  (exc/try-on (+ 1 nil))
  ;; => #<Failure [#<NullPointerException java.lang.NullPointerException>]>
  ----
  
  _cats_ comes with other syntactic sugar macros: `try-or-else` that returns a default value if a
  computation fails, and `try-or-recover` that lets you handle the return value when executing a
  function with the exception as first parameter.
  
  .Usage example of `try-or-else` macro.
  [source, clojure]
  ----
  (exc/try-or-else (+ 1 nil) 2)
  ;; => #<Success [2]>
  ----
  
  .Usage example of `try-or-recover` macro.
  [source, clojure]
  ----
  (exc/try-or-recover (+ 1 nil)
                      (fn [e]
                        (cond
                          (instance? NullPointerException e) 0
                          :else 100)))
  ;; => #<Success [0]>
  ----
  
  The types defined for the Exception monad (Success and Failure) also implement the Clojure IDeref
  interface, which allows library development using monadic composition without forcing a user of
  that library to use or understand monads.
  
  That is because when you dereference the failure instance, it will reraise the
  enclosed exception.
  
  .Example dereferencing a failure instance
  [source, clojure]
  ----
  (def f (exc/try-on (+ 1 nil)))
  
  @f
  ;; => NullPointerException   clojure.lang.Numbers.ops (Numbers.java:961)
  ----
  
  
  === Validation
  
  The validation type is similar to the Either or Exception types except that it
  doesn't implement a Monad instance. It has two constructors: `ok` and `fail`,
  representing success and failure respectively.
  
  [source, clojure]
  ----
  (require '[cats.applicative.validation :as v])
  (require '[cats.core :as m])
  
  (v/ok 42)
  ;; => #<Ok 42>
  
  (v/fail [])
  ;; => #<Fail []>
  ----
  
  It implements the Applicative protocol, and its intended usage is as an Applicative. Applying Validation
  values together errs on the side of the failure, and applying failures together aggregates their values
  using the Semigroup's `mappend` function.
  
  [source, clojure]
  ----
  (require '[cats.applicative.validation :as v])
  (require '[cats.core :as m])
  
  (m/fapply (v/ok 42) (v/fail "OH NOES"))
  ;; => #<Fail "OH NOES">
  
  ;; Note that `<*>` is a variadic fapply
  (m/<*> (v/ok 42)
         (v/fail {:foo "bar"})
         (v/fail {:baz "fubar"})
         (v/ok 99))
  ;; => #<Fail {:baz "fubar", :foo "bar"}>
  ----
  
  
  === Built in types
  
  Some of the abstractions in _cats_ are implemented for built-in types but you can't use them directly. First,
  you must load the `cats.builtin` namespace:
  
  [source, clojure]
  ----
  (use 'cats.builtin)
  (require '[cats.core :as m])
  
  (m/fmap inc [1 2 3 4])
  ;; => [2 3 4 5]
  ----
  
  
  ==== nil
  
  Given the fact that `nil` is both a value and a type, we have extended the `nil` type to be equivalent
  to Maybe monad's `Nothing`. This means that you can use `nil` as if were a `Just` instance like in the
  following example:
  
  [source, clojure]
  ----
  (use 'cats.builtin)
  (require '[cats.core :as m])
  (require '[cats.monad.maybe :as maybe])
  
  (m/mlet [x (maybe/just 42)
           y nil]
    (m/return (+ x y)))
  ;; => nil
  ----
  
  As you can see, the `mlet` short-circuits when encountering a `nil` value.
  
  
  ==== Vector
  
  Clojure vectors also participate in several of the abstractions implemented in _cats_, most notably
  as a monad. Compare the following `for` comprehension:
  
  [source, clojure]
  ----
  (for [x [1 2]
        y [3 4 5]]
     (+ x y))
  ;; => (4 5 6 5 6 7)
  ----
  
  with the equivalent using _mlet_:
  
  [source, clojure]
  ----
  (use 'cats.builtin)
  (require '[cats.core :as m])
  
  (m/mlet [x [1 2]
           y [3 4 5]]
    (m/return (+ x y)))
  ;; => [4 5 6 5 6 7]
  ----
  
  Note the symmetry between `for` and `mlet`. This is not accidental, both are what is called a monad comprehension,
  the difference is that `for` is limited to sequences and `mlet` can work with arbitrary monads.
  
  Also, since `mlet` desugars into calls to the Monad's `bind` function, its result keeps the type of the monadic values.
  
  
  ==== Lazy sequences
  
  Lazy sequences implement the same abstractions as vectors with practically an identical implementation. If you don't need
  the results right away or are interested in a subset of the final results, you can use lazy sequence comprehensions.
  
  Using `mlet` with lazy sequences yields exactly the same result as using `for`:
  
  [source, clojure]
  ----
  (use 'cats.builtin)
  (require '[cats.core :as m])
  
  (m/mlet [x (lazy-seq [1 2])
           y (lazy-seq [3 4 5])]
    (m/return (+ x y)))
  ;; => (4 5 6 5 6 7)
  ----
  
  
  ==== Set
  
  Sets implement almost every abstraction in _cats_, from Semigroup to Monad.
  
  [source, clojure]
  ----
  (use 'cats.builtin)
  (require '[cats.core :as m])
  
  (m/pure set-monad 42)
  ;; => #{42}
  
  (m/fmap inc #{1 2 3 4})
  ;; => #{4 3 2 5}
  
  (m/bind #{1 2 3}
          (fn [v] #{v (inc v)}))
  ;; => #{1 4 3 2}
  ----
  
  
  ==== Map
  
  Maps implement the _Semigroup_ protocol, since we can use `merge` as their associative binary operation. Using
  `mappend` on maps is a way to merge them together:
  
  [source, clojure]
  ----
  (use 'cats.builtin)
  (require '[cats.core :as m])
  
  (m/mappend {:a "A"} {:b "B"})
  ;; => {:a "A", :b "B"}
  ----
  
  Since we can consider the empty map an identity element for the `mappend` associative binary operation maps also
  implement _Monoid_ and the `mempty` function gives an empty map.
  
  
  == Syntax sugar
  
  === mlet
  
  For convenience when using the monadic bind the `mlet` macro is implemented in cats. If you've followed along
  with the documentation you've seen many examples of its usage already, let's see what can `mlet` do.
  
  NOTE: If you are coming from Haskell, mlet is analogous to the *do notation*.
  
  First of all, mlet turns this let-like bindings
  
  [source, clojure]
  ----
  (m/mlet [a (maybe/just 1)
           b (maybe/just (inc a))]
    (m/return (* a b)))
  ----
  
  into a chain of calls to bind:
  
  [source, clojure]
  ----
  (m/bind (maybe/just 1)
          (fn [a]
            (m/bind (maybe/just (inc a))
                    (fn [b]
                      (m/return (* a b))))))
  ----
  
  This makes a lot more natural to write code that uses monads.
  
  Since the bindings in the mlet macro run the monadic effects of the right-hand values we cannot just put
  any value in there and expect to be bound to its left symbol. For cases where we want the regular behavior
  of let we can inline a `:let` clause, just like with Clojure's `for`:
  
  [source, clojure]
  ----
  (m/mlet [a (maybe/just 1)
           b (maybe/just (inc a))
           :let [z (+ a b)]]
    (m/return (* z 2)))
  ----
  
  `mlet` has support for using guards using a `:when` clause, analogous to the one used in `for`. We can filter out values
  using `bind` with `mlet` and `:when` like the following:
  
  [source, clojure]
  ----
  (require '[cats.core :as m])
  (require '[cats.monad.maybe :as maybe])
  
  (m/mlet [a (maybe/just 1)
           :when (= a 2)]
     (m/return (* a 2)))
  ;; => #<Nothing >
  ----
  
  Any monadic type that implements `MonadZero` can be combined with guards inside `mlet` bindings. Here is an example with
  vectors:
  
  [source, clojure]
  ----
  (require '[cats.builtin]
  (require '[cats.core :as m])
  
  (m/mlet [a [1 2 3 4]
           :when (odd? a)]
     (m/return (* a 2)))
  ;; => [2 6]
  ----
  
  === alet
  
  One limitation of monadic bind is that all the steps are strictly sequential and
  happen one at a time. This piece of code illustrates the usage of monadic bind:
  