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.
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:
Hi, I stumbled into a very similar usecase, and I do require knowing the element in a container. Here’s the example:
from typing import Callable, Iterable, Sequence
type CostFunction[T] = Callable[[T], float]
# Sequence[T] gives an error, because T is not concrete
def get_lowest_cost_sequence[T, S: Sequence[T]](
seqs: Iterable[S], item_cost: CostFunction[T]
) -> S:
def seq_cost(seq: S) -> float:
return sum(item_cost(t) for t in seq)
return sorted(seqs, key=seq_cost)[0]
Seems to me full HKT isn’t required for generic upper bounds to be possible/useful. Here’s my thinking:
If the generic upper bound is in the type parameter list, with the inner TypeVar also in the type parameter list, then all the types are concrete - we are just binding identifiers to different parts of the overall type.
So if all the TypeVars and upper bounds are “self contained” in this way, it seems possible to allow generic upper bounds.
How would one go about proposing this and/or proving it out?