erlang-bugs リストでバグを報告した副作用として、dialyzer と typer の発明者である Kostis Sagonas から詳細な回答を得ました。
私の側の質問に対して、次の素晴らしい詳細な回答を得ました。
2011 年 5 月 1 日 (日) 午後 5 時 53 分、Kostis Sagonas は次のように書いています。
Peer Stritzinger は次のように書いています。
ところで: typer で --annotate を実行してから、手動で調整された仕様なしでdialyzerを実行したときに警告が表示されないのは正常ですか
はい。実際、typer は、dialyzer の基本的な型推論のフロント エンドにすぎません (つまり、警告識別コンポーネントはありません)。
IMO、取得した仕様を手動で「マッサージ」し、それらの一部についてより多くの情報を提供するつもりがない場合、これを行う意味はほとんどありません。以前のプログラムを見てみましょう。次のように型を導入すると、2 つの << :64, :_*8>> 型が同じ数量を参照していたという事実をより適切に表現できます。
-type packet() :: <<_:64,_:_*8>>,
チャネルについても同様:
-type channel() :: atom() | pid() |{atom(),_}.
そうすれば、スペックはすでに見栄えが良くなります。また、dialyzer/typer には、関数の 2 番目の引数で使用する予定の fun のタイプに関する情報がありrecv/3
ませんが、そうします! コードから、レコードが必要であることは明らかな#can_pkt{}
ので、そのフィールドに適切な型を追加して、型を導入してみませんか?
-record(can_pkt, {id :: id(), data :: binary(), timestamp :: ts()}).
-type can_pkt() :: #can_pkt{}.
その後、仕様ははるかに良く見える可能性があります:
-spec recv(packet(), fun((can_pkt()) -> R), channel()) -> R.
-spec decode(packet()) -> can_pkt().
また、プレースホルダー型変数を使用して、関数が 2 番目の引数の fun が返す型を何でも返すR
という事実を示していることに注意してください。recv/2
おそらくこのタイプが何であるかを知っているので、タイプを導入して適切な名前を使用する必要があります。
お役に立てれば、
コスティス
PS。上記に含まれる情報は実際のバグよりも興味深いものであるため、これを erlang-bugs に投稿したのは残念です。
彼はコード フラグメントを参照しているので、バグ レポートに含めました。ここに含めます。次のコード フラグメントは、 によって自動的に注釈が付けられましたtyper --annotate
。
-record(can_pkt, {id, data, timestamp}).
-spec recv(<<_:64,_:_*8>>,fun((_) ->
any()),atom() | pid() | {atom(),_}) -> any().
recv(Packet, Recv_fun, Chan) ->
P = decode(Packet),
#can_pkt{id=Can_id, data=Can_data}=P,
Recv_fun(P).
-spec decode(<<_:64,_:_*8>>) ->
#can_pkt{id::<<_:11>>,data::binary(),timestamp::char()}.
decode(<<_:12, Len:4, Timestamp:16,
0:3, Id:11/bitstring, 0:18,
Data:Len/binary, _/binary>>) ->
#can_pkt{id=Id, data=Data, timestamp=Timestamp}.