7

私はオンラインブック「Learn you some erlang」を興味深く読んでおり、理解度を確認するためにいくつかの演習を試みています。

型仕様と Erlangの章で fifo の例にいくつかの変更を加え、「typed_fifo(T)」 (すべての要素が同じ型 T でなければならない fifo) を定義しようとしました。

私のタイプの仕様は次のとおりです。

-type typed_empty_fifo() :: {fifo, [], []}.

-type typed_nonempty_fifo(A) :: {fifo, nonempty_list(A), list(A)} | {fifo, [],nonempty_list(A) }.

-type typed_fifo(A) :: typed_empty_fifo() | typed_nonempty_fifo(A)。

そして、次の関数仕様で使用すると:

-spec empty (typed_empty_fifo()) -> true;

  (typed_nonempty_fifo(_)) -> false.

空 ({fifo、[]、[]}) -> 真;

is_list(A), is_list(B) -> false の場合は empty({fifo, A, B})。

ダイアライザーは、ドメインが重複しているため指定を無視することを通知します。

誰かがどこで間違いを犯したか教えてもらえますか?

別のポイントがあります。型付き fifo を定義しようとする前に、適切に機能するバージョンがありました。ダイアライザーは、不適切なリストの使用を妨げるものは何もないことを示しています。驚いたことに、リストの適切な/不適切な文字をテストする (ガードで使用できる) 簡単な方法が見つかりません。

これは本当に奇妙です。bif の長さ/1 を使用すると、badarg という理由で失敗する可能性があるからです。

23>L=[1,2|3]。==> [1,2|3]

24> is_list(L). ==>真

25>長さ(L)。==> 例外エラー: 不正な引数

 in function  length/1

    called as length([1,2|3])

ありがとう

4

2 に答える 2

4

タイプと仕様に問題はありません。問題は、型の表現のためにDialyzerで使用されるデータ型が、提供しているほどの精度を維持しないことです。具体的には、タプルは同じアリティ(3)と最初のアトム要素( )を持っているため、ユニオン:はに{fifo, nonempty_list(A), list(A)} | {fifo, [], nonempty_list(A)}「押しつぶされ」ます。Dialyzerは通常、型分析をより効率的にするために(ここでも確認できるように)過剰近似を行います。この警告は無視してかまいません。{fifo, list(A), list(A)}fifo

2番目の質問でis_list/1は、引数として渡される用語の最初のコンストラクターがconsセルであるかどうかのみを確認します。もis_list([1|2])返しますtrue

引数が適切なリストであることを確認したい場合は、次のcaseような式でカスタム関数を使用できます。

case is_proper_list(L) of
  true -> ...;
  false -> ...
end

is_proper_list([]) -> true;
is_proper_list([_|L]) -> is_proper_list(L);
is_proper_list(_) -> false.

ただし、これをガードに配置することはできません。警備員では、以下のコメントで提案したものを使用できます(length(L) >= 0)。

于 2012-08-30T19:24:02.343 に答える
0

2番目の質問に関して、正しい作業方法listは次のとおりです。

1> L = [1,2|[3]].
[1,2,3]
2> is_list(L).
true
3> length(L).
3

[Head|Tail]表記では、あなたTaillist(not ) である必要があることに注意してくださいint

于 2012-08-30T13:49:23.990 に答える