2017-04-09 23 views
3
-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 

同樣是這個 「預期」 的行爲?

回答

3

是的,它似乎是「預計」。源代碼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不會)...

3

是的,這是「預期」行爲。或者說「接受」。

免責聲明:

  1. 透析從未答應過捕獲所有的錯誤。
  2. 上面的代碼是相當人爲的。

說明:

透析器的設計師們決定使用overapproximations這樣的(除其他原因)使刀具的類型推斷分析終止分析遞歸函數時(到達固定點)(中內部步驟實際上是這樣的:「factorial的基本情況適用於0,所以它的遞歸情況也適用於1,所以它也適用於2,所以它也適用於3,[...],所以它適用於12,好,所以它也適用於任何char(),但它也適用於char_range + 1,因此適用於所有integers()「)。

這個(任意的確實)極限變得非常罕見,然後再次,Dialyzer從未承諾報告任何東西......