Erlang 从超类型中排除类型
Erlang exclude type from supertype
在 Erlang 中,是否可以通过从超类型中排除子类型来定义类型?例如,我将如何定义一个“除 pid()
之外的任何类型”的类型:
-type anything_but_pid() :: ...?
阅读有关主管数据类型的文档,我遇到了 this type spec for child_id()
,它将类型定义为 term()
,然后说 Not a pid()
下面的评论:
child_id() = term()
Not a pid()
.
如果我不想明确列出所有可能的类型,这是我能做的最好的事情吗?
作为一个可能的解决方法,您可以像这样为您的函数定义一个规范:
-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()
当然,这并不能一概而论...
不,从 OTP 23(甚至 24)开始,这不受支持。
此外,在这种情况下期望 Dialyzer 提供帮助是不明智的,因为 Dialyzer 通常过于逼近,出于多种原因,尽管我认为它不会将这种类型转变为 term()
立即,它很可能会在第一个给定的机会时这样做(例如,无论您在哪里调用这样的函数)。
在 Erlang 中,是否可以通过从超类型中排除子类型来定义类型?例如,我将如何定义一个“除 pid()
之外的任何类型”的类型:
-type anything_but_pid() :: ...?
阅读有关主管数据类型的文档,我遇到了 this type spec for child_id()
,它将类型定义为 term()
,然后说 Not a pid()
下面的评论:
child_id() = term()
Not a
pid()
.
如果我不想明确列出所有可能的类型,这是我能做的最好的事情吗?
作为一个可能的解决方法,您可以像这样为您的函数定义一个规范:
-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()
当然,这并不能一概而论...
不,从 OTP 23(甚至 24)开始,这不受支持。
此外,在这种情况下期望 Dialyzer 提供帮助是不明智的,因为 Dialyzer 通常过于逼近,出于多种原因,尽管我认为它不会将这种类型转变为 term()
立即,它很可能会在第一个给定的机会时这样做(例如,无论您在哪里调用这样的函数)。