Как использовать переменные универсального (высшего типа) типа в системе подсказок типа Python?

Предположим, я хочу написать универсальный класс, используя mypy, но аргумент типа для класса сам по себе является универсальным типом. Например:

from typing import TypeVar, Generic, Callable

A = TypeVar("A")
B = TypeVar("B")
T = TypeVar("T")


class FunctorInstance(Generic[T]):
    def __init__(self, map: Callable[[Callable[[A], B], T[A]], T[B]]):
        self._map = map

    def map(self, x: T[A], f: Callable[[A], B]) -> T[B]:
        return self._map(f, x)

Когда я пытаюсь вызвать mypy в приведенном выше определении, я получаю сообщение об ошибке:

$ mypy typeclasses.py 
typeclasses.py:9: error: Type variable "T" used with arguments
typeclasses.py:12: error: Type variable "T" used with arguments 

Я попытался добавить ограничения в определение T TypeVar, но не смог заставить это работать. Можно ли сделать это?


person Rafael S. Calsaverini    schedule 09.01.2019    source источник


Ответы (2)


В настоящее время, на момент написания, проект mypy не поддерживает типы более высокого типа. См. следующую проблему github:

https://github.com/python/typing/issues/548

person juanpa.arrivillaga    schedule 09.01.2019

Пакет returns теперь предоставляет некоторую стороннюю поддержку HKT.

Чтобы скопировать фрагмент из своих документов

>>> from returns.primitives.hkt import Kind1
>>> from returns.interfaces.container import Container1
>>> from typing import TypeVar

>>> T = TypeVar('T', bound=Container1)

>>> def to_str(arg: Kind1[T, int]) -> Kind1[T, str]:
...   ...

Ваш Functor был бы чем-то похож

from typing import TypeVar, Generic, Callable

A = TypeVar("A")
B = TypeVar("B")
T = TypeVar("T")


class FunctorInstance(Generic[T]):
    def __init__(
        self, map: Callable[[Callable[[A], B], Kind1[T, A]], Kind1[T, B]]
    ):
        self._map = map

    def map(self, x: Kind1[T, A], f: Callable[[A], B]) -> Kind1[T, B]:
        return self._map(f, x)
person joel    schedule 15.11.2020