   "The Validation applicative implementation and helper functions
   for validating values. Isomorphic to Either."
   (:require [cats.protocols :as p]
-            [cats.core :as m]
             [cats.monad.either :as either]))
 
 (declare validation-applicative)


    (fapply [_ af av]
      (cond
        (and (ok? af) (ok? av)) (ok ((m/extract af) (m/extract av)))
        (and (fail? af) (fail? av)) (fail (m/mappend (m/extract af) (m/extract av)))
        (ok? af) av
        :else af))))


    p/Semigroup
    (mappend [_ sv sv']
      (cond
        (and (fail? sv) (fail? sv'))
        (fail (let [sv (p/extract sv)
                    sv' (p/extract sv')]
                (p/mappend (p/get-context sv) sv sv')))

        (ok? sv) sv
        :else sv'))

