| // `optionalZip` because `zip` caused ambiguity with `Publisher.zip` in the implementation below. | |
| private func optionalZip<Left, Right>(_ pair: (Left?, Right?)) -> (Left, Right)? { | |
| pair.0.flatMap { left in pair.1.map { right in (left, right) } } | |
| } | |
| extension Publisher { | |
| func pairwiseWithDuplicatedStart() -> AnyPublisher<(Output, Output), Failure> { | |
| scan((nil, nil)) { previousPair, next in | |
| optionalZip(previousPair) | |
| .map { ($0.1, next) } ?? (next, next) // (1) | |
| } | |
| .compactMap(optionalZip) | |
| .eraseToAnyPublisher() | |
| } | |
| } | |
| let cancellable = (1...2) | |
| .publisher | |
| .pairwiseWithDuplicatedStart() | |
| .sink(receiveValue: { print($0) }) | |
| // Outputs (without the annotations): | |
| // ``` | |
| // (1, 1) | |
| // (1, 2) | |
| // ``` |