通过类型注释对Python中的类型构造函数进行抽象

时间:2018-09-07 10:49:04

标签: python static-analysis static-typing mypy higher-kinded-types

我想静态地强制类的方法返回包装在某种抽象类型中的值,而我对此一无所知:

例如给定抽象类

F = ???    

class ThingF(Generic[F]):
    @abstractmethod
    def action(self) -> F[Foo]:
        ...

我希望能够静态检查这是否无效:

class ThingI(ThingF[List]):
    def action(self) -> Foo:
        ...

因为action不返回List[Foo]

但是上述ThingF的声明甚至都没有运行,因为Generic期望它的参数是类型变量,而我无法找到一种方法来使F成为类型变量“孔”。

两者

F = TypeVar('F')

T = TypeVar('T')
F = Generic[T]

不起作用,因为TypeVar不可下标,或者Generic[~T]不能用作类型变量。

如果需要的话,我基本上想要的是一个“更高种类的类型变量”,它是类型构造函数的抽象。即上面写着“ F可以是采用另一种类型来产生具体类型的任何类型”。

有什么方法可以使用Python的类型注释来表达它,并用mypy对其进行静态检查?

2 个答案:

答案 0 :(得分:1)

不幸的是,类型系统(如PEP 484中所述)不支持更高类型的类型-这里有一些相关的讨论:https://github.com/python/typing/issues/548

mypy和其他类型检查工具可能会在将来的某个时候获得它们的支持,但我不会屏住呼吸。要实现这一目标,需要进行一些相当复杂的实施工作。

答案 1 :(得分:1)

您可以对dry-python/returns使用高级类型。 我们同时提供了原语和自定义mypy插件,以使其正常工作。

以下是MappableFunctor的示例:

from typing import Callable, TypeVar

from returns.interfaces.mappable import MappableN
from returns.primitives.hkt import Kinded, KindN, kinded

_FirstType = TypeVar('_FirstType')
_SecondType = TypeVar('_SecondType')
_ThirdType = TypeVar('_ThirdType')
_UpdatedType = TypeVar('_UpdatedType')

_MappableKind = TypeVar('_MappableKind', bound=MappableN)


@kinded
def map_(
    container: KindN[_MappableKind, _FirstType, _SecondType, _ThirdType],
    function: Callable[[_FirstType], _UpdatedType],
) -> KindN[_MappableKind, _UpdatedType, _SecondType, _ThirdType]:
    return container.map(function)

它将适用于任何Mappableexamples

from returns.maybe import Maybe

def test(arg: float) -> int:
        ...

reveal_type(map_(Maybe.from_value(1.5), test))  # N: Revealed type is 'returns.maybe.Maybe[builtins.int]'

并且:

from returns.result import Result

def test(arg: float) -> int:
    ...

x: Result[float, str]
reveal_type(map_(x, test))  # N: Revealed type is 'returns.result.Result[builtins.int, builtins.str]'

它肯定有一些限制,例如:它仅适用于直接的Kind子类型,并且我们需要单独的别名Kind1Kind2Kind3等。因为当时mypy不支持可变参数泛型。

来源:https://github.com/dry-python/returns/blob/master/returns/primitives/hkt.py 插件:https://github.com/dry-python/returns/blob/master/returns/contrib/mypy/_features/kind.py

文档:https://returns.readthedocs.io/en/latest/pages/hkt.html

公告帖子:https://sobolevn.me/2020/10/higher-kinded-types-in-python