   single element in the result sequence."
   ([f ob]
    #?(:cljs (.reduce ob #(f %1 %2))
-      :clj  (.reduce ob (as-bifunction f))))
+      :clj  (cond
+              (observable? ob)
+              (-> (.reduce ob (as-bifunction f))
+                  (as-observable))
+
+              (flowable? ob)
+              (-> (.reduce ob (as-bifunction f))
+                  (as-flowable))
+
+              :else (throw (IllegalArgumentException. "`ob` should be observable or flowable")))))
+
   ([f seed ob]
    #?(:cljs (.reduce ob #(f %1 %2) seed)
-      :clj  (.reduce ob seed (as-bifunction f)))))
+      :clj  (cond
+              (observable? ob)
+              (-> (.reduce ob seed (as-bifunction f))
+                  (as-observable))
+
+              (flowable? ob)
+              (-> (.reduce ob seed (as-bifunction f))
+                  (as-flowable))
+
+              :else (throw (IllegalArgumentException. "`ob` should be observable or flowable"))))))
 
 (defn scan
   "Applies an accumulator function over an observable

#?(:clj
   (defn flowable?
     "Check if the provided value is Flowable instance."
     [o]
     (instance? Flowable o)))

#?(:clj
   (defn single?


(defn transform
  "Transform the observable sequence using transducers."
  [xform ob]
  (when-not (observable? ob)
    (throw (IllegalArgumentException. "Only observables are supported")))
  (letfn [(sink-step [sink]
            (fn
              ([r] (sink end) r)
