Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

One reduce overload to match reductions is missing. #241

Open
JessyCatterwaul opened this issue Aug 29, 2024 · 0 comments
Open

One reduce overload to match reductions is missing. #241

JessyCatterwaul opened this issue Aug 29, 2024 · 0 comments

Comments

@JessyCatterwaul
Copy link

Four of the six reductions overloads correspond to a reduce overload from the standard library.

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 }
}
@JessyCatterwaul JessyCatterwaul changed the title The reduce overload to match reductions is missing. One reduce overload to match reductions is missing. Aug 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant