Erlang Dialyzer 整数范围
Erlang Dialyzer integer ranges
-module(test).
-export([f/0, g/0]).
-spec f() -> RESULT when
RESULT :: 0..12 .
-spec g() -> RESULT when
RESULT :: 0..13 .
f () -> 100 .
g () -> 100 .
运行 透析器(和打字机)仅捕获函数 f
。
dialyzer test.erl
Checking whether the PLT /Users/ben/.dialyzer_plt is up-to-date... yes
Proceeding with analysis...
test.erl:4: Invalid type specification for function test:f/0. The success typing is () -> 100
done in 0m0.53s
done (warnings were emitted)
与打字机相同
typer test.erl
typer: Error in contract of function test:f/0
The contract is: () -> RESULT when RESULT :: 0..12
but the inferred signature is: () -> 100
这是"expected"行为吗?
是的,它似乎确实是 "expected"。
查看源代码here
它针对
的值进行测试
-define(SET_LIMIT, 13).
在测试中
t_from_range(X, Y) when is_integer(X), is_integer(Y) ->
case ((Y - X) < ?SET_LIMIT) of
true -> t_integers(lists:seq(X, Y));
false ->
case X >= 0 of
false ->
if Y < 0 -> ?integer_neg;
true -> t_integer()
end;
true ->
if Y =< ?MAX_BYTE, X >= 1 -> ?int_range(1, ?MAX_BYTE);
Y =< ?MAX_BYTE -> t_byte();
Y =< ?MAX_CHAR, X >= 1 -> ?int_range(1, ?MAX_CHAR);
Y =< ?MAX_CHAR -> t_char();
X >= 1 -> ?integer_pos;
X >= 0 -> ?integer_non_neg
end
end
end;
恕我直言,这似乎很危险,并且不提供任何真正的保证。绝对应该清楚地记录下来。 learn you some Erlang 网站上有传递参考。
A range of integers. For example, if you wanted to represent a number
of months in a year, the range 1..12 could be defined. Note that
Dialyzer reserves the right to expand this range into a bigger one.
但 google 的首页上没有任何官方使用关键字 dialyzer integer ranges
编辑...如果您尝试仔细观察,您会发现:
-module(test).
-export([h/0]).
-spec h() -> RESULT when
RESULT :: 1..13 .
h () -> 100 .
Dialyzer 会捕获错误! (Typer 不会)...
是的,这是“预期的”行为。或者更确切地说是“接受”。
免责声明:
- Dialyzer 从未承诺会捕获所有错误。
- 像上面这样的代码是相当人为的。
解释:
Dialyzer 的设计者已决定使用这样的过度逼近(除其他原因外)使工具的类型推断分析在分析递归函数时终止(达到固定点)(内部步骤实际上如下所示:“阶乘的基本情况适用于 0,所以它的递归情况也适用于 1,所以它也适用于 2,所以它也适用于 3,[...],所以它适用于 12,好的,所以它也适用于任何 char()
,但它也适用于 char_range + 1
,因此它适用于所有 integers()
")。
这个(实际上是任意的)限制变得至关重要的情况相当罕见,而且,Dialyzer 从未承诺报告任何事情...
-module(test).
-export([f/0, g/0]).
-spec f() -> RESULT when
RESULT :: 0..12 .
-spec g() -> RESULT when
RESULT :: 0..13 .
f () -> 100 .
g () -> 100 .
运行 透析器(和打字机)仅捕获函数 f
。
dialyzer test.erl
Checking whether the PLT /Users/ben/.dialyzer_plt is up-to-date... yes
Proceeding with analysis...
test.erl:4: Invalid type specification for function test:f/0. The success typing is () -> 100
done in 0m0.53s
done (warnings were emitted)
与打字机相同
typer test.erl
typer: Error in contract of function test:f/0
The contract is: () -> RESULT when RESULT :: 0..12
but the inferred signature is: () -> 100
这是"expected"行为吗?
是的,它似乎确实是 "expected"。 查看源代码here 它针对
的值进行测试-define(SET_LIMIT, 13).
在测试中
t_from_range(X, Y) when is_integer(X), is_integer(Y) ->
case ((Y - X) < ?SET_LIMIT) of
true -> t_integers(lists:seq(X, Y));
false ->
case X >= 0 of
false ->
if Y < 0 -> ?integer_neg;
true -> t_integer()
end;
true ->
if Y =< ?MAX_BYTE, X >= 1 -> ?int_range(1, ?MAX_BYTE);
Y =< ?MAX_BYTE -> t_byte();
Y =< ?MAX_CHAR, X >= 1 -> ?int_range(1, ?MAX_CHAR);
Y =< ?MAX_CHAR -> t_char();
X >= 1 -> ?integer_pos;
X >= 0 -> ?integer_non_neg
end
end
end;
恕我直言,这似乎很危险,并且不提供任何真正的保证。绝对应该清楚地记录下来。 learn you some Erlang 网站上有传递参考。
A range of integers. For example, if you wanted to represent a number of months in a year, the range 1..12 could be defined. Note that Dialyzer reserves the right to expand this range into a bigger one.
但 google 的首页上没有任何官方使用关键字 dialyzer integer ranges
编辑...如果您尝试仔细观察,您会发现:
-module(test).
-export([h/0]).
-spec h() -> RESULT when
RESULT :: 1..13 .
h () -> 100 .
Dialyzer 会捕获错误! (Typer 不会)...
是的,这是“预期的”行为。或者更确切地说是“接受”。
免责声明:
- Dialyzer 从未承诺会捕获所有错误。
- 像上面这样的代码是相当人为的。
解释:
Dialyzer 的设计者已决定使用这样的过度逼近(除其他原因外)使工具的类型推断分析在分析递归函数时终止(达到固定点)(内部步骤实际上如下所示:“阶乘的基本情况适用于 0,所以它的递归情况也适用于 1,所以它也适用于 2,所以它也适用于 3,[...],所以它适用于 12,好的,所以它也适用于任何 char()
,但它也适用于 char_range + 1
,因此它适用于所有 integers()
")。
这个(实际上是任意的)限制变得至关重要的情况相当罕见,而且,Dialyzer 从未承诺报告任何事情...