 
 (defn left
   "A Left type constructor."
-  ([] (Left. nil))
-  ([v] (Left. v)))
+  ([] (->Left nil))
+  ([v] (->Left v)))
 
 (defn right
   "A Right type constructor."
-  ([] (Right. nil))
-  ([v] (Right. v)))
+  ([] (->Right nil))
+  ([v] (->Right v)))
 
 (defn left?
   "Return true if `v` is an instance


(declare context)

(deftype Right [v]
  p/Contextual
  (-get-context [_] context)

  p/Extract
  (-extract [_] v)

  p/Printable
  (-repr [_]
    (str "#<Right " (pr-str v) ">"))

  #?@(:cljs [cljs.core/ILookup
             (-lookup
               [this k]
                 (if (= k :right) @this nil))
             (-lookup
               [this k not-found]
                 (if (= k :right) @this not-found))]
      :clj  [clojure.lang.ILookup
             (valAt
               [this k]
                 (if (= k :right) @this nil))
             (valAt
               [this k not-found]
                 (if (= k :right) @this not-found))])

  #?@(:cljs [cljs.core/IDeref
             (-deref [_] v)]
      :clj  [clojure.lang.IDeref
             (deref [_] v)])

  #?@(:clj
      [Object
       (equals [self other]
         (if (instance? Right other)
           (= v (.-v ^Right other))
           false))]

      :cljs
      [cljs.core/IEquiv
       (-equiv [_ other]
         (if (instance? Right other)
           (= v (.-v ^Right other))
           false))]))

(deftype Left [v]
  p/Contextual
  (-get-context [_] context)

  p/Extract
  (-extract [_] v)

  p/Printable
  (-repr [_]
    (str "#<Left " (pr-str v) ">"))

  #?@(:cljs [cljs.core/ILookup
             (-lookup
               [this k]
                 (if (= k :left) @this nil))
             (-lookup
               [this k not-found]
                 (if (= k :left) @this not-found))]
      :clj  [clojure.lang.ILookup
             (valAt
               [this k]
                 (if (= k :left) @this nil))
             (valAt
               [this k not-found]
                 (if (= k :left) @this not-found))])

  #?@(:cljs [cljs.core/IDeref
             (-deref [_] v)]
      :clj  [clojure.lang.IDeref
             (deref [_] v)])

  #?@(:clj
      [Object
       (equals [self other]
         (if (instance? Left other)
           (= v (.-v ^Left other))
           false))]

      :cljs
      [cljs.core/IEquiv
       (-equiv [_ other]
         (if (instance? Left other)
           (= v (.-v ^Left other))
           false))]))

(alter-meta! #'->Right assoc :private true)
(alter-meta! #'->Left assoc :private true)

    p/Functor
    (-fmap [_ f s]
      (if (right? s)
        (right (f (p/-extract ^Right s)))
        s))

    p/Bifunctor
    (-bimap [_ f g s]
      (if (left? s)
        (left  (f (p/-extract ^Left s)))
        (right (g (p/-extract ^Right s)))))

    p/Applicative
    (-pure [_ v]
