Erlang从超类型中排除类型



在Erlang中,是否可以通过从超类型中排除子类型来定义类型?作为一个例子,我将如何定义一个类型;除了pid()之外的任何东西:

-type anything_but_pid() :: ...?

在阅读有关主管数据类型的文档时,我发现了child_id()的类型规范,它将类型定义为term(),然后在下面的评论中说Not a pid()

child_id() = term()

不是pid()

如果我不想显式列出所有可能的类型,这是我能做的最好的事情吗?

否,从OTP 23(甚至24(起,这是不受支持的。

此外,在这种情况下,期望Dialyzer提供帮助是不明智的,因为Dialyzer通常过于近似,原因有几个,尽管我不认为它会立即将这样的类型转换为term(),但它很可能会在第一个给定的机会(例如,无论你在哪里调用这样的函数(就这样做。

作为一种可能的解决方法,您可以为您的函数定义一个规范,如下所示:

-spec foo(pid()) -> ...;
(any()) -> ...
foo(data) when is_pid(data) -> error;
foo(data) -> ....

特别是对于anything_but_pid(),您可以"简单地";列举所有其他选项:

-type anything_but_pid() :: port()
| reference()
| atom()
| bitstring()
| number()
| fun()
| maybe_improper_list()
| map()
| tuple()

当然,这并不能一概而论。。。

最新更新