Open
Description
Four of the six reductions
overloads correspond to a reduce
overload from the standard library.
- This
reduce
overload 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