How do you pause (single-pass) Sequences?

Edit: The answer is: this is one of AnyIterator's uses—it is, itself, a Sequence!

public extension AnyIterator {
  /// A single-pass version of a sequence,
  /// whose iteration can be "paused", if not fully-consumed in one operation.
  init<Sequence: Swift.Sequence>(pauseable sequence: Sequence)
  where Sequence.Element == Element {
    self.init( sequence.makeIterator() )
  }
}
let upperBound = 5
let pauseableRange = AnyIterator(pauseable: 1...upperLimit)

for _ in pauseableRange.prefix(1) { }

func doNothin<NothinDoin>(_: NothinDoin) { }
pauseableRange.prefix(1).forEach(doNothin)
_ = pauseableRange.prefix(1).map(doNothin)

XCTAssertEqual(
  Array(pauseableRange), Array(4...upperBound)
)

Could you explain what it means pause a sequence?

If you've got a better term for it, I'm totally open to it. As long as it makes that test pass, it's probably good.

Another example:

public struct FibonacciSequence<Number: AdditiveArithmetic & ExpressibleByIntegerLiteral> {
  public init() { }

  private var numbers: (Number, Number) = (0, 1)
}

extension FibonacciSequence: Sequence, IteratorProtocol {
  public mutating func next() -> Number? {
    defer { numbers = (numbers.1, numbers.0 + numbers.1) }
    return numbers.0
  }
}

(Imagine it with numbers way bigger than 10):

typealias Number = Int
let pauseableFibonacciSequence =
  AnyIterator( pauseable: FibonacciSequence<Number>() )

func getNext(_ count: Int) -> [Number] {
  .init( pauseableFibonacciSequence.prefix(count) )
}

XCTAssertEqual(getNext(10), [0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
XCTAssertEqual(getNext(10), [55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181])

Ok, I see what you're trying to do. I don't know why you'd want to model it as Sequence instead of directly using IteratorProtocol.

If you own the type, maybe you can model Sequence as a class conforming to both IteratorProtocol and Sequence, and have makeIterator returns self. If you want to have both non-pausing and pausing versions, or you don't own the type, I couldn't think of a better way compared to your AnySequence.

1 Like

I didn't know that AnyIterator was a Sequence. Man, that's confusing. Thanks!