
PEP 646 brought us variadic generics, which are great, but consider these functions: def product(it1: Iterable[T1], it2: Iterable[T2]) -> Iterable[Tuple[T1, T2]]: ... def zip(it1: Iterable[T1], it2: Iterable[T2]) -> Iterable[Tuple[T1, T2]]: ... def map(f: Callable[[T1, T2], S], it1: Iterable[T1], it2: Iterable[T2]) -> Iterable[S]: ... def make_boxed(x1: T1, x2: T2) -> Tuple[Boxed[T1], Boxed[T2]]: ... If I wanted to generalize them to arbitrary arguments, my naive solution would be something like this: def product(*it: *Iterable[Ts]) -> Iterable[Tuple[*Ts]]: ... def zip(*it: *Iterable[Ts]) -> Iterable[Tuple[*Ts]]: ... def map(f: Callable[[*Ts], S], *it: *Iterable[Ts]) -> Iterable[S]: ... def make_boxed(*x: *Ts) -> Tuple[*Boxed[Ts]]: ... But this obviously doesn't work. And it's also hard to see how it could be made to work because `Iterable` can't be unpacked. Has anyone thought about this? It seems like it would be a very useful feature for typing the standard library. (The title calls this "patterned" because that's what was used in this Swift design doc: https://github.com/hborla/swift-evolution/blob/variadic-generics-vision/visi... ) Regards, Thomas