Erlang透析器整数范围

问题描述:

-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 . 

运行dialyzer(和typer)只有函数f被捕获。Erlang透析器整数范围

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 

同样是这个 “预期” 的行为?

是的,它似乎是“预计”。源代码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网站上有传递参考。

一系列整数。例如,如果您想表示一年中的月份数 ,则可以定义1..12的范围。请注意, 透析器保留将此范围扩展到更大范围的权利。使用关键字dialyzer integer ranges谷歌的头版

但没有正式

编辑...看起来有点接近,你可以看到,如果你尝试:

-module(test). 
-export([h/0]). 

-spec h() -> RESULT when 
     RESULT :: 1..13 . 

h() -> 100 . 

透析器将捕获错误! (Typer不会)...

是的,这是“预期”行为。或者说“接受”。

免责声明:

  1. 透析从未答应过捕获所有的错误。
  2. 上面的代码是相当人为的。

说明:

透析器的设计师们决定使用overapproximations这样的(除其他原因)使刀具的类型推断分析终止分析递归函数时(到达固定点)(中内部步骤实际上是这样的:“factorial的基本情况适用于0,所以它的递归情况也适用于1,所以它也适用于2,所以它也适用于3,[...],所以它适用于12,好,所以它也适用于任何char(),但它也适用于char_range + 1,因此适用于所有integers()“)。

这个(任意的确实)极限变得非常罕见,然后再次,Dialyzer从未承诺报告任何东西......