2012-02-17 5 views
1

doブロック内でパターンが一致するのはなぜですか?これらのパターンマッチは重複しているのはなぜですか?

(q, m) <- newRq 
let m2 = appendMsg "first" key m 
    (q4, m4) = case m2 of 
       m -> deleteRec key q m2 
       _ -> (q, m2) 

これは警告

Warning: Pattern match(es) are overlapped 
     In a case alternative: _ -> ... 

でコンパイルし、私がしたいように動作しません。 (q4、m4)の場合は、常にそれが返されるようです。

[], fromList [] 

m2とmの値は無視されます。私はそれらを期待していないローカル変数はありますか?

単語で達成したいこと:m2とmが等しい場合、(q4、m4)はdeleteRec key q m2に、そうでない場合は(q、m2)になるはずです。

答えて

11

casem)の最初のパターンはすべて一致し、mに割り当てられます。 2番目のものはすべて一致し、それを破棄しますが(_)、mがすべてを取得するため、一致するものは残っていません。

私はあなたがケースがswitchのように動作することを意図していたと思いますが、実際には関数宣言のようなパターンのセットとして機能します。だからあなたのcaseのようなものと同じです。このコードで

check m2 
    where check m = deleteRec key q m2 
     check _ = (q, m2) 

、あなただけifを使用してオフおそらく最高だ:

if m == m2 then deleteRec key q m2 else (q, m2) 

あなたはまた違ったif文をインデント検討するかもしれない:

if m == m2 
then deleteRec key q m2 
else (q, m2) 

も有効です。

しかし、一般的には、あなたが実際にcase文で警備員を使用することができますので、これはあまりにも動作します:

case m2 of 
    val | m2 == m -> deleteRec key q m2 
     | otherwise -> (q, m2) 

これは明らかにifよりも読むのが大変ですが、あなたはより多くの枝を持っていたか、必要であれば、実際のパターンマッチングを行うには、それは意味をなさないでしょう。

+0

trueの場合はtrueですが、私はいつもそれが慣用ではないことを読んでいるので、避けるために1時間座っていました。ハスケルの開発者は可能な限りパターンマッチングを使用するべきです。 –

+3

はい、できるだけパターンマッチングを使用してください*。しかし、変数の* value *と照合することはできません。パターン内の変数は、何かを取ることができる '_'のような単なる「穴」です。その名前にそこにあったものを割り当てます。 –

+0

if-then-elseの代替手段はまだありますか? –

関連する問題