 (defn nothing
   "A Nothing type constructor."
   []
-  (Nothing.))
+  (assoc (Nothing.) :nothing nil))
 
 (defn just?
   "Returns true if `v` is an instance


(declare context)

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

  p/Extract
  (-extract [_] v)

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

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

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

  #?@(:clj
      [Object
       (equals [self other]
         (if (instance? Just other)
           (= v (.-v ^Just other))
           false))]
      :cljs
      [cljs.core/IEquiv
       (-equiv [_ other]
         (if (instance? Just other)
           (= v (.-v ^Just other))
           false))]))

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


  (-repr [_]
    "#<Nothing>")

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

(alter-meta! #'->Nothing assoc :private true)
(alter-meta! #'->Just assoc :private true)
