Erlang:为什么 Dialyzer 没有注意到这个错误?
Erlang: Why Dialyzer does not notice this error?
现在,我尝试使用 Dialyzer 并使用 -spec、-type。
我将以下代码提供给 Dialyzer,我希望 Dialyzer 注意到 "hoge(a) + 1 is invalid",但 Dialyzer 没有注意到。
-spec hoge (X) -> bad when X :: a;
(X) -> number() when X :: number().
hoge(X) when is_number(X) -> 1;
hoge(a) -> bad.
foo() ->
_ = hoge(a) + 1.
但是,在另一个设置中,
-spec hoge (X) -> bad when X :: a;
(X) -> string() when X :: number().
hoge(X) when is_number(X) -> "1";
hoge(a) -> bad.
foo() ->
_ = hoge(a) + 1.
Dialyzer 告诉我这个错误,
test.erl:12: The call erlang:'+'('bad' | [49,...],1) will never return since it differs in the 1st argument from the success typing arguments: (number(),number())
为什么 Dialyzer 在第一次设置时无法注意到类型错误。
-spec hoge (X) -> bad when X :: a;
(X) -> number() when X :: number().
这个合同(规范)不是"hoge is typed of 'a' -> 'bad' | number() -> number()"而是“'a' | number() -> 'bad' | number()”?
这是第一个示例的完整模块。
-module(example).
-export([hoge/1, foo/0]).
-spec hoge (X) -> bad when X :: a;
(X) -> number() when X :: number().
hoge(X) when is_number(X) -> 1;
hoge(a) -> bad.
foo() ->
_ = hoge(a) + 1.
"why Dialyzer doesn't catch this error" 个问题的标准答案始终是 "because it is never wrong"。 Dialyzer 从不承诺找出所有错误。
在您的问题示例中,如果没有规范,Dialyzer 的类型推断算法确实会为所有参数和所有 return 值生成联合类型。使用规范,Dialyzer 仍然推断联合,但是 应该 使用规范来缩小调用的 return 值,然后产生错误。这看起来像 "reduced sensitivity" 的情况(但本身不是错误)。在任何情况下,您都可以提交错误报告。
在您的工作示例中,任何可能的值都会导致错误的结果,即使没有规范,Dialyzer 自己的类型推断也足够了。
现在,我尝试使用 Dialyzer 并使用 -spec、-type。
我将以下代码提供给 Dialyzer,我希望 Dialyzer 注意到 "hoge(a) + 1 is invalid",但 Dialyzer 没有注意到。
-spec hoge (X) -> bad when X :: a;
(X) -> number() when X :: number().
hoge(X) when is_number(X) -> 1;
hoge(a) -> bad.
foo() ->
_ = hoge(a) + 1.
但是,在另一个设置中,
-spec hoge (X) -> bad when X :: a;
(X) -> string() when X :: number().
hoge(X) when is_number(X) -> "1";
hoge(a) -> bad.
foo() ->
_ = hoge(a) + 1.
Dialyzer 告诉我这个错误,
test.erl:12: The call erlang:'+'('bad' | [49,...],1) will never return since it differs in the 1st argument from the success typing arguments: (number(),number())
为什么 Dialyzer 在第一次设置时无法注意到类型错误。
-spec hoge (X) -> bad when X :: a;
(X) -> number() when X :: number().
这个合同(规范)不是"hoge is typed of 'a' -> 'bad' | number() -> number()"而是“'a' | number() -> 'bad' | number()”?
这是第一个示例的完整模块。
-module(example).
-export([hoge/1, foo/0]).
-spec hoge (X) -> bad when X :: a;
(X) -> number() when X :: number().
hoge(X) when is_number(X) -> 1;
hoge(a) -> bad.
foo() ->
_ = hoge(a) + 1.
"why Dialyzer doesn't catch this error" 个问题的标准答案始终是 "because it is never wrong"。 Dialyzer 从不承诺找出所有错误。
在您的问题示例中,如果没有规范,Dialyzer 的类型推断算法确实会为所有参数和所有 return 值生成联合类型。使用规范,Dialyzer 仍然推断联合,但是 应该 使用规范来缩小调用的 return 值,然后产生错误。这看起来像 "reduced sensitivity" 的情况(但本身不是错误)。在任何情况下,您都可以提交错误报告。
在您的工作示例中,任何可能的值都会导致错误的结果,即使没有规范,Dialyzer 自己的类型推断也足够了。