Generics over container types?

Given that I have a function:

def process[T](collection: Sequence[T]) -> Sequence[T]

I want to express that, when the input is of type list[T], the return value will be list[T], when the input is of type tuple[T, ...], the return value will be tuple[T, ...]. Its means that the container type (list, tuple, Deque) of the return value is in accordance with the input.

How should I make type annotation?

That’s what upper bounds in a TypeVar are for, in your simple example, you should be able to express it like this:

def process[T: Sequence](collection: T) -> T: ...

Thank you, how to annotate the element type also, like Sequence[U]? Is this valid:

def process[T: Sequence[U]](collection: T) -> T: ...

No, this requires higher kinded types, which are not supported yet.

Technically speaking this isn’t HKT, but rather a generic type-parameter bound.

Also note that in this example U only appears once, so there is no need for it. So even if Python would support generic type-parameter bounds or HKT, then the above would be equivalent to:

def process[T: Sequence[object]](collection: T) -> T: ...

So this already works :slight_smile:

1 Like