How can I use the data from a variadic tuple, for reduction as an example

I've seen samples of how to pass along variadic types and values, but how do I actually extract answers? For instance, if I have a variadic function that takes types conforming to Collection, then apply isEmpty to each collection, how can I reduce the new tuple of Bool values (like && or ||)?

You unfortunately can't do this directly yet. But the following works in Swift 6. Is this useful to you?

func reduce<each C: Collection, Result, E: Error>(
  _ collection: repeat each C,
  initialResult: Result,
  nextPartialResult: (Result, any Collection) throws(E) -> Result
) throws(E) -> Result {
  var result = initialResult
  for collection in repeat each collection {
    result = try nextPartialResult(result, collection)
  }
  return result
}
@Test func reduce() {
  var allAreEmpty = reduce([], 1...10, initialResult: true) { $0 && $1.isEmpty }
  #expect(!allAreEmpty)
  allAreEmpty = reduce([], [], [], initialResult: true) { $0 && $1.isEmpty }
  #expect(allAreEmpty)
}
1 Like

You can kinda do this in Swift 5.x by exploiting an inner helper function, and make the helper function throw. That will allow you to make some test, on each variadic parameter. If nothing throws, the test has passed for all params.

private struct NotEmptyError: Error {}
func isEmpty<each C: Collection>(_ collection: repeat each C) -> Bool {
    func throwIfNonEmpty(c: some Collection) throws {
        guard c.isEmpty else { throw NotEmptyError() }
        return
    }
    do {
        try (repeat throwIfNonEmpty(c: each collection))
        return true
    } catch {
        return false
    }
}

print(isEmpty([], 1..<1, ""))  // true
print(isEmpty([], 1..<10, ""))  // false
2 Likes