我正在使用类型提示实现幺半群。为此我写了:
M = TypeVar('M')
class Monoid(Generic[M]):
...
def append(self, m: 'Monoid[M]') -> 'Monoid[M]':
raise NotImplementedError()
在子类中使用它时,例如
A = TypeVar('A')
class List(Monoid[A], Generic[A]):
def __init__(self, *values: A) -> None:
self._values = tuple(values)
...
def append(self, m: 'List[A]') -> 'List[A]':
return List(*(self.values + m.values))
我得到error: Argument 1 of "append" incompatible with supertype "Monoid"
。由于List
是Monoid
的正确子类,我希望能够输入。我做错了什么?
答案 0 :(得分:1)
好吧,你的List
类不是一个正确的Monoid子类型。毕竟,你声明所有Monoids必须有一个append方法,可以接受Monoid的任意Monoid或子类 - 所以,为什么缩小List以使其append
只能接受专门的List?
这违反了Liskov substitution principle。
您可以使用generic self:
解决此特定情况M = TypeVar('M')
T = TypeVar('T')
class Monoid(Generic[M]):
...
def append(self: T, m: T) -> T:
raise NotImplementedError()
现在,您要表示Monoid
的所有子类都必须实现一个append
方法,该方法特别接受该子类类型。使用这个新版本的Monoid,您的List类现在是类型安全的。