<p>下面是一个相对Pythonic方式的sum类型的实现。</p>
<pre><code>import attr
@attr.s(frozen=True)
class CombineMode(object):
kind = attr.ib(type=str)
params = attr.ib(factory=list)
def match(self, expected_kind, f):
if self.kind == expected_kind:
return f(*self.params)
else:
return None
@classmethod
def join(cls):
return cls("join")
@classmethod
def select(cls, column: str):
return cls("select", params=[column])
</code></pre>
<p>打开一个翻译,你会看到熟悉的行为:</p>
<pre><code>>>> CombineMode.join()
CombineMode(kind='join_by_entity', params=[])
>>> CombineMode.select('a') == CombineMode.select('b')
False
>>> CombineMode.select('a') == CombineMode.select('a')
True
>>> CombineMode.select('foo').match('select', print)
foo
</code></pre>
<p>注意:<code>@attr.s</code>decorator来自<a href="http://www.attrs.org/en/stable/examples.html" rel="nofollow noreferrer">attrs library</a>,它实现<code>__init__</code>、<code>__repr__</code>和<code>__eq__</code>,但它也冻结对象。我加入它是因为它减少了实现的规模,但它也广泛可用,而且相当稳定。</p>
<p>求和类型有时称为标记联合。在这里,我使用了<code>kind</code>成员来实现标记。附加的每变量参数通过列表实现。在真正的Pythonic方式中,这是在输入和输出端输入的duck类型,但没有在内部严格执行。</p>
<p>我还包含了一个<code>match</code>函数,它执行基本模式匹配。类型安全也通过duck类型实现,如果传递的lambda函数签名与您试图匹配的实际变量不一致,则会引发<code>TypeError</code>。</p>
<p>这些求和类型可以与产品类型(<code>list</code>或<code>tuple</code>)组合,并且仍然保留代数数据类型所需的许多关键功能。</p>
<p><strong>问题</strong></p>
<p>这并不严格限制变量集。</p>