 
 (declare context)
 
-(deftype Right [v]
+(defrecord Right [right]
   p/Contextual
   (-get-context [_] context)
 
   p/Extract
-  (-extract [_] v)
+  (-extract [_] right)
 
   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))])
+    (str "#<Right " (pr-str right) ">"))
 
   #?@(:cljs [cljs.core/IDeref
-             (-deref [_] v)]
+             (-deref [_] right)]
       :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]
+             (deref [_] right)]))
+
+(defrecord Left [left]
   p/Contextual
   (-get-context [_] context)
 
   p/Extract
-  (-extract [_] v)
+  (-extract [_] left)
 
   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))])
+    (str "#<Left " (pr-str left) ">"))
 
   #?@(:cljs [cljs.core/IDeref
-             (-deref [_] v)]
+             (-deref [_] left)]
       :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))]))
+             (deref [_] left)]))
 
 (alter-meta! #'->Right assoc :private true)
 (alter-meta! #'->Left assoc :private true)

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

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

    p/Applicative
    (-pure [_ v]


(defn left
  "A Left type constructor."
  ([] (->Left nil))
  ([v] (->Left v)))

(defn right
  "A Right type constructor."
  ([] (->Right nil))
  ([v] (->Right v)))

(defn left?
  "Return true if `v` is an instance
