func combineLatest<P, T>(
    _ other: P,
    _ transform: @escaping (Self.Output, P.Output) -> T
) -> Publishers.Map<Publishers.CombineLatest<Self, P>, T> 
where P : Publisher, Self.Failure == P.Failure

Generic P T가 있는데 P 는 퍼블리셔 타입이고 현재 퍼블리셔의 실패타입과 P타입의 실패타입이 같아야함.

T 는 클로저의 리턴타입으로 딱히 제너릭 제약사항이없음.

let upstream = PassthroughSubject<Int,Never>()
let second = PassthroughSubject<String, Never>()
upstream.combineLatest(second)
    .sink(receiveCompletion: {print("\\($0)")}, receiveValue: {print("\\($0) \\($1)")})

upstream.send(1)
upstream.send(2)
second.send("A")
upstream.send(3)
upstream.send(4)
/*
2 A
3 A
4 A
*/
let pub1 = PassthroughSubject<Int, Never>()
let pub2 = PassthroughSubject<Int, Never>()

let cancellable = pub1
    .combineLatest(pub2)
    .sink { print("Result: \\($0).") }

pub1.send(1)
pub1.send(2)
pub2.send(2)
pub1.send(3)
pub1.send(45)
pub2.send(22)

퍼블리셔의 Output타입이 서로 다를 경우에는 $0,$1처럼 되지만 같은 경우에는 튜플로 방출됨.

이런 방식으로 4개의 퍼블리셔를 묶을수 있음.