2

I'd like to type erase AsyncMapSequence<AsyncThrowingStream<Element, Error>, Element>. My consumer doesn't care whether the sequence has been transformed, or how it has been transformed.

Ideally this could be type erased to the original stream type (AsyncThrowingStream<Element, Error>). Is that possible?

This is my attempt:

extension AsyncMapSequence {
    func eraseToAsyncThrowingStream() -> AsyncThrowingStream<Element, Error> {
        AsyncThrowingStream { continuation in
            Task.detached {
                do {
                    var iterator = self.makeAsyncIterator()
                    while let element = try await iterator.next() {
                        continuation.yield(element)
                    }
                    continuation.finish()
                } catch {
                    continuation.finish(throwing: error)
                }
            }
        }
    }
}

but that yields this error...

Fatal error: attempt to await next() on more than one task

I'm also not super sure why transforming a stream becomes a sequence

Will Alexander
  • 337
  • 2
  • 16
  • Think my error might have been related to another issue (consuming the same stream in more than one task). Without that I think this code does in fact work. :) – Will Alexander Apr 30 '23 at 17:29
  • 2
    You probably want to look at AsyncChannel for this kind of problem: https://github.com/apple/swift-async-algorithms/blob/main/Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/Channel.md – Rob Napier Apr 30 '23 at 18:07

1 Answers1

2

I believe this can be done more simply and generally with init(unfolding:) (I haven't done much testing on this, but I don't see any reason it shouldn't work):

extension AsyncSequence {
    func eraseToAsyncThrowingStream() -> AsyncThrowingStream<Element, Error> {
        var iterator = self.makeAsyncIterator()
        return AsyncThrowingStream(unfolding: { try await iterator.next() })
    }
}

I recommend reading over the AnyAsyncSequence thread in the Swift forums for some further (and future) thoughts on the underlying question.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610