- 
                Notifications
    
You must be signed in to change notification settings  - Fork 467
 
Open
Description
Four of the six reductions overloads correspond to a reduce overload from the standard library.
- This 
reduceoverload is missing. - reductions(_:)
 - lazy version
 
The missing overload should return nil, for empty sequences.
@Test func reduce() {
  let sequence = [1, 2, 3, 4]
  #expect(sequence.reductions(+) == [1, 3, 6, 10])
  #expect(sequence.reduce(+) == 10)
  #expect(EmptyCollection<Int>().reductions(+) == [])
  #expect(EmptyCollection<Int>().reduce(+) == nil)
}Here's an implementation without typed throws:
public extension Sequence
  @inlinable func reduce(
    _ nextPartialResult: (Element, Element) throws -> Element
  ) rethrows -> Element? {
    var iterator = makeIterator()
    return try iterator.next().map { first in
      try IteratorSequence(iterator).reduce(first, nextPartialResult)
    }
  }
}Typed throws should be used, however.
  @inlinable func reduce<Error>(
    _ nextPartialResult: (Element, Element) throws(Error) -> Element
  ) throws(Error) -> Element? {
    var iterator = makeIterator()
    return try iterator.next().map { first throws(Error) in
      try forceCastError(
        to: Error.self,
        IteratorSequence(iterator).reduce(first, nextPartialResult)
      )
    }
  }/// A mechanism to interface between untyped and typed errors.
///
/// When you know for certain that a value may only throw one type of error,
/// but that guarantee is not (or, due to compiler bugs, cannot be) represented in the type system,
/// you can use this to "convert" it to "typed throws".
/// - Parameters:
///   - errorType: The error type known for certain to be thrown by `value`.
///   - value: A value that might throw an `Error`.
/// - Important: A crash will occur if `value` throws any type but `Error`.
/// - Bug: [`errorType` must be explicitly provided](https://github.com/swiftlang/swift/issues/75674).
public func forceCastError<Value, Error>(
  to errorType: Error.Type = Error.self,
  _ value: @autoclosure () throws -> Value
) throws(Error) -> Value {
  do { return try value() }
  catch { throw error as! Error }
}Metadata
Metadata
Assignees
Labels
No labels