我有一个泛型类(比如Automata[S]
),我希望另一个非泛型类(比如Test
)将Automata[S]
作为一些S
的字段(即,我希望将∃S. Automata[S]
作为字段)
我的第一次尝试是使用unsubscribedAutomata
类型对字段进行注释,如下所示。但是delta
和is_finale
的应用程序不是类型安全的,因为类型参数S
变成了Any
import abc
from typing import Generic, TypeVar
S = TypeVar('S')
class Automata(Generic[S], metaclass=abc.ABCMeta):
@abc.abstractmethod
def initial_state(self) -> S:
raise NotImplementedError()
@abc.abstractmethod
def delta(self, state: S, x: int) -> S:
raise NotImplementedError()
@abc.abstractmethod
def is_final(self, state: S) -> bool:
raise NotImplementedError()
class Counter(Automata[int]):
def initial_state(self) -> int:
return 0
def delta(self, state: int, x: int) -> int:
return state + x
def is_final(self, state: int) -> bool:
return state >= 10
class Test:
automata: Automata
def __init__(self, automata: Automata[S]):
self.automata = automata
def test(self) -> bool:
s0 = self.automata.initial_state()
# reveal_type(self.automata) #=> Automata[Any]
# reveal_type(s0) #=> Any
s1 = self.automata.delta(s0, 1)
s2 = self.automata.delta(s1, 2)
s3 = self.automata.delta(s2, 3)
return self.automata.is_final(s3)
test = Test(Counter())
test.test()
我的另一个尝试是使用同构∃X. F(X) ≅ ∀R. (∀X. F(X) → R) → R
,如下所示。它看起来是类型安全的,因为显示的类型不是Any
,但是为每次写入continuation而对Cont
进行子类化是冗长且有点复杂的
import abc
from typing import Generic, TypeVar
S = TypeVar('S')
R = TypeVar('R')
class Automata(Generic[S], metaclass=abc.ABCMeta):
@abc.abstractmethod
def initial_state(self) -> S:
raise NotImplementedError()
@abc.abstractmethod
def delta(self, state: S, x: int) -> S:
raise NotImplementedError()
@abc.abstractmethod
def is_final(self, state: S) -> bool:
raise NotImplementedError()
class Counter(Automata[int]):
def initial_state(self) -> int:
return 0
def delta(self, state: int, x: int) -> int:
return state + x
def is_final(self, state: int) -> bool:
return state >= 10
class Cont(Generic[R], metaclass=abc.ABCMeta):
@abc.abstractmethod
def __call__(self, automata: Automata[S]) -> R:
raise NotImplementedError()
class EAutomata(metaclass=abc.ABCMeta):
"""
∃S. Automata[S]
"""
@abc.abstractmethod
def unpack(self, cont: Cont[R]) -> R:
raise NotImplementedError()
@staticmethod
def pack(automata: Automata[S]) -> 'EAutomata':
return EAutomataBody[S](automata)
class EAutomataBody(EAutomata, Generic[S]):
def __init__(self, automata: Automata[S]):
self._automata = automata
def unpack(self, cont: Cont[R]) -> R:
return cont(self._automata)
class Test:
automata: EAutomata
def __init__(self, automata: Automata[S]):
self.automata = EAutomata.pack(automata)
def test(self) -> bool:
class C(Cont[bool]):
def __call__(self, automata: Automata[S]) -> bool:
s0 = automata.initial_state()
# reveal_type(automata) #=> Automata[S`-1]
# reveal_type(s0) #=> S`-1
s1 = automata.delta(s0, 1)
s2 = automata.delta(s1, 2)
s3 = automata.delta(s2, 3)
return automata.is_final(s3)
return self.automata.unpack(C())
test = Test(Counter())
test.test()
有没有办法简化上述方法,或者有没有更好的办法在Python中使用存在类型
目前没有回答
相关问题 更多 >
编程相关推荐