diff --git a/Sources/AsyncAlgorithms/AsyncExclusiveReductionsSequence.swift b/Sources/AsyncAlgorithms/AsyncExclusiveReductionsSequence.swift index 582317c1..4cfba6bf 100644 --- a/Sources/AsyncAlgorithms/AsyncExclusiveReductionsSequence.swift +++ b/Sources/AsyncAlgorithms/AsyncExclusiveReductionsSequence.swift @@ -14,15 +14,18 @@ extension AsyncSequence { /// Returns an asynchronous sequence containing the accumulated results of combining the /// elements of the asynchronous sequence using the given closure. /// - /// This can be seen as applying the reduce function to each element and - /// providing the initial value followed by these results as an asynchronous sequence. + /// Starting from the initial value, this combines each element of the base + /// asynchronous sequence with the running result and emits each intermediate + /// result. The initial value itself is not emitted, so the first element of + /// the returned sequence is the result of combining the initial value with + /// the first element of the base sequence. If the base sequence is empty, the + /// returned sequence is also empty. /// /// - Parameters: /// - initial: The value to use as the initial value. /// - transform: A closure that combines the previously-reduced result and /// the next element in the receiving asynchronous sequence, which it returns. - /// - Returns: An asynchronous sequence of the initial value followed by the reduced - /// elements. + /// - Returns: An asynchronous sequence of the reduced elements. @available(AsyncAlgorithms 1.0, *) @inlinable public func reductions( @@ -37,16 +40,19 @@ extension AsyncSequence { /// Returns an asynchronous sequence containing the accumulated results of combining the /// elements of the asynchronous sequence using the given closure. /// - /// This can be seen as applying the reduce function to each element and - /// providing the initial value followed by these results as an asynchronous sequence. + /// Starting from the initial value, this combines each element of the base + /// asynchronous sequence with the running result and emits each intermediate + /// result. The initial value itself is not emitted, so the first element of + /// the returned sequence is the result of combining the initial value with + /// the first element of the base sequence. If the base sequence is empty, the + /// returned sequence is also empty. /// /// - Parameters: /// - initial: The value to use as the initial value. /// - transform: A closure that combines the previously-reduced result and /// the next element in the receiving asynchronous sequence, mutating the /// previous result instead of returning a value. - /// - Returns: An asynchronous sequence of the initial value followed by the reduced - /// elements. + /// - Returns: An asynchronous sequence of the reduced elements. @available(AsyncAlgorithms 1.0, *) @inlinable public func reductions( diff --git a/Sources/AsyncAlgorithms/AsyncThrowingExclusiveReductionsSequence.swift b/Sources/AsyncAlgorithms/AsyncThrowingExclusiveReductionsSequence.swift index 35ea3ef5..14c2fc2c 100644 --- a/Sources/AsyncAlgorithms/AsyncThrowingExclusiveReductionsSequence.swift +++ b/Sources/AsyncAlgorithms/AsyncThrowingExclusiveReductionsSequence.swift @@ -14,16 +14,19 @@ extension AsyncSequence { /// Returns an asynchronous sequence containing the accumulated results of combining the /// elements of the asynchronous sequence using the given error-throwing closure. /// - /// This can be seen as applying the reduce function to each element and - /// providing the initial value followed by these results as an asynchronous sequence. + /// Starting from the initial value, this combines each element of the base + /// asynchronous sequence with the running result and emits each intermediate + /// result. The initial value itself is not emitted, so the first element of + /// the returned sequence is the result of combining the initial value with + /// the first element of the base sequence. If the base sequence is empty, the + /// returned sequence is also empty. /// /// - Parameters: /// - initial: The value to use as the initial value. /// - transform: A closure that combines the previously reduced result and /// the next element in the receiving asynchronous sequence and returns /// the result. If the closure throws an error, the sequence throws. - /// - Returns: An asynchronous sequence of the initial value followed by the reduced - /// elements. + /// - Returns: An asynchronous sequence of the reduced elements. @available(AsyncAlgorithms 1.0, *) @inlinable public func reductions( @@ -38,8 +41,12 @@ extension AsyncSequence { /// Returns an asynchronous sequence containing the accumulated results of combining the /// elements of the asynchronous sequence using the given error-throwing closure. /// - /// This can be seen as applying the reduce function to each element and - /// providing the initial value followed by these results as an asynchronous sequence. + /// Starting from the initial value, this combines each element of the base + /// asynchronous sequence with the running result and emits each intermediate + /// result. The initial value itself is not emitted, so the first element of + /// the returned sequence is the result of combining the initial value with + /// the first element of the base sequence. If the base sequence is empty, the + /// returned sequence is also empty. /// /// - Parameters: /// - initial: The value to use as the initial value. @@ -47,8 +54,7 @@ extension AsyncSequence { /// the next element in the receiving asynchronous sequence, mutating the /// previous result instead of returning a value. If the closure throws an /// error, the sequence throws. - /// - Returns: An asynchronous sequence of the initial value followed by the reduced - /// elements. + /// - Returns: An asynchronous sequence of the reduced elements. @available(AsyncAlgorithms 1.0, *) @inlinable public func reductions( diff --git a/Tests/AsyncAlgorithmsTests/TestReductions.swift b/Tests/AsyncAlgorithmsTests/TestReductions.swift index ba4366ea..f460c3e4 100644 --- a/Tests/AsyncAlgorithmsTests/TestReductions.swift +++ b/Tests/AsyncAlgorithmsTests/TestReductions.swift @@ -27,6 +27,34 @@ final class TestReductions: XCTestCase { XCTAssertNil(pastEnd) } + func test_reductions_empty() async { + let sequence = [Int]().async.reductions("") { partial, value in + partial + "\(value)" + } + var iterator = sequence.makeAsyncIterator() + var collected = [String]() + while let item = await iterator.next() { + collected.append(item) + } + XCTAssertEqual(collected, []) + let pastEnd = await iterator.next() + XCTAssertNil(pastEnd) + } + + func test_throwing_reductions_empty() async throws { + let sequence = [Int]().async.reductions("") { (partial, value) throws -> String in + partial + "\(value)" + } + var iterator = sequence.makeAsyncIterator() + var collected = [String]() + while let item = try await iterator.next() { + collected.append(item) + } + XCTAssertEqual(collected, []) + let pastEnd = try await iterator.next() + XCTAssertNil(pastEnd) + } + func test_inclusive_reductions() async { let sequence = [1, 2, 3, 4].async.reductions { $0 + $1 } var iterator = sequence.makeAsyncIterator()