2016-07-28 10 views
3

私の質問は既存のquestion(と彼はErlang自体の既知のバグだったことを驚いていました!私は本の同じcount_charactersの例を使用していますが、R19にあっても同じエラーが発生します。マップを使用しているときに不正なパターンがあります

コード:

% Frequency count of characters in a string 
count_characters(Str) -> 
    count_characters(Str, #{}). 

count_characters([H|T], #{ H => N }=X) -> 
    count_characters(T, X#{ H := N+1 }); 
count_characters([H|T], X) -> 
    count_characters(T, X#{ H => 1 }); 
count_characters([], X) -> X. 

とエラー:ここ

1> c(lib_misc). 
lib_misc.erl:40: illegal pattern 
lib_misc.erl:41: variable 'N' is unbound 
error 

ライン40はcount-characters/2の最初の句を指します。

私の質問は以下のとおりです。

  • 私はバグがリンクされSO質問からである正確に理解することはできませんよ。誰かがエラーを引き起こしている変数とその理由を簡単に説明できますか?
  • これはまだR19で修正されていますか?そうでない場合は、いつですか?それは非常にひどく壊れている例を提供する著者の本を見て悲しいです。

リンクされたページで受け入れられた回答はmaps:updateのようなものを使用しています。私は同じことをすることができますが、私は最初にエラーが存在する理由を知りたいです。

答えて

4

現在表示されているエラーはErlangのバグに由来していません。 =>は、マップの作成には:=が使用されています(どちらも更新が許可されています)。:=はすでにマップ内のキーに対してのみ機能し、=>は新しいキーを追加できます。だから、パターンで:=が必要になります。

count_characters([H|T], #{ H := N }=X) -> 
    % H => N+1 is also legal here, and means the same because we know H is a key of X 
    count_characters(T, X#{ H := N+1 }); 

をただし、あなたが問題に実行しないこの問題を解決した後:H#{ H := N }パターンではまだ拘束されていないが、これは現在サポートされていません。これは、複数の引数パターンを順番に照合することで修正できるため、H[H|T]にバインドされます。これはR19Bでは行われていません(少なくともこの例から判断してください)、これを変更する計画があるかどうかはわかりません。個人的にパターンが同時にチェックされるのは私にとって意味があります。だから私はこの変更が望ましいとは確信していません。

あなたは最初の2つの句を組み合わせて、代わりにヘッドの本体でXを照合することによってこの問題を回避することができます

count_characters([H|T], X) -> 
    case X of 
     #{ H := N } -> count_characters(T, X#{ H => N+1 }); 
     _ -> count_characters(T, X#{ H => 1 }) 
    end; 
count_characters([], X) -> X. 
+0

うーん。 。 。 ':='はマップのキーを更新し、別のマップに使用するのではありませんか?パターンマッチングよりも構造に似ています(またはそうではないかもしれませんが、確かに建設が関係しています)。 – dotslash

+0

'#{H:= N}'に束縛されていない 'H 'については、本書の第2版は具体的に次のように書いています:"最初の節では、 の変数Hも地図の外に定義されます。 (必要に応じて)バインドされています。真剣に、このすべての混乱はかなり腐敗しています。 :( – dotslash

+2

マップを更新すると、 '=>'と ':='の両方が可能になります( ':='はマップに既に存在するキーに対してのみ機能し、 '=>'は新しいキーを追加できます)。 –

関連する問題