-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 .
Running dialyzer (and typer) only the function f
is caught.
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)
the same with typer
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
Is this "expected" behaviour?
2条答案
按热度按时间vfhzx4xs1#
Yes it does seem to be "expected". Looking at the source code here It tests against the value of
-define(SET_LIMIT, 13).
in the test
IMHO this seems dangerous, and does not provide any real guarantees. It should definitely be documented clearly. there is passing reference on the learn you some Erlang website.
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.
But nothing official on the front page of google using the keywords
dialyzer integer ranges
Edit... looking a bit closer you can see that if you try:
Dialyzer will catch the error! (Typer will not) ...
2ic8powd2#
是的,这是“预期的”行为,或者更确切地说是“被接受的”行为。
声明:
1.透析器从来没有承诺捕捉所有的错误。
1.像上面这样的代码是相当人工的。
说明:
透析器的设计者决定使用这样的过度近似(除了其他原因之外),以使工具的类型推理分析在分析递归函数时终止(达到固定点)(内部步骤实际上如下所示:“阶乘的基本情况适用于0,所以它的递归情况也适用于1,所以它也适用于2,所以它也适用于3,[...],所以它适用于12,好的,所以它也适用于任何
char()
,但它也适用于char_range + 1
,所以它适用于所有integers()
“)。这是相当罕见的,这个(确实是任意的)限制变得关键,然后再一次,透析器从来没有承诺报告任何事情...