         }
         
         if let error = error {
-            throw error
+            return SequenceMaterializeResult.failed(elements: elements, error: error)
         }
         
-        return elements
+        return SequenceMaterializeResult.completed(elements: elements)
+    }
+    
+    fileprivate func elementsOrThrow(_ results: SequenceMaterializeResult<E>) throws -> [E] {
+        switch results {
+        case .failed(_, let error):
+            throw error
+        case .completed(let elements):
+            return elements
+        }
     }
 }

    ///
    /// - returns: All elements of sequence.
    public func toArray() throws -> [E] {
        return try convertToArray()
    }
}


    /// - parameter predicate: A function to test each source element for a condition.
    /// - returns: Returns the only element of an sequence that satisfies the condition in the predicate, and reports an error if there is not exactly one element in the sequence.
    public func single(_ predicate: @escaping (E) throws -> Bool) throws -> E? {
        let results = convertToArray(max: 2, predicate: predicate)
        let elements = try elementsOrThrow(results)
        
        switch elements.count {
        case 0:
