20

関数の複数のパターン一致を定義する場合、たとえば次のようになります。

1: takeTree 0 tree                           = Leaf
2: takeTree levels (Leaf)                    = Leaf
3: takeTree levels (Branch value left right) = Branch value (takeTree...

特に2つの警告が表示されます。

Source.hs:1:警告:定義されていますが使用されていません: `tree '

Source.hs:2:警告:定義されていますが使用されていません: `levels '

しかし、これらが有用な警告であるとすぐには確信していません。私のコードが代わりだった場合:

1: takeTree 0 _                              = Leaf
2: takeTree _ (Leaf)                         = Leaf
3: takeTree levels (Branch value left right) = Branch value (takeTree...

これにより、警告が修正され、読みにくくなり、入力値として期待するセマンティクスがわかりにくくなりました。

Defined but not used私の徹底的なパターンの中で、各引数が実際に少なくとも1回使用されているのに、なぜここで合理的な警告があるのでしょうか。

4

3 に答える 3

45

何かが名前を付けるのに十分重要である場合、それは使用するのに十分重要であるに違いないという仮定は、多くのコーディング スタイルで合理的です。

しかし、ケーキを持って食べることもできます。

takeTree 0 _tree                           = Leaf
takeTree _levels (Leaf)                    = Leaf
takeTree levels (Branch value left right)  = Branch value (takeTree...

名前の先頭のアンダースコアは、その名前がこの式で使用されることを意図していないことを人間の読者とコンパイラの両方に知らせますが、単一のアンダースコアよりも長い名前は、人間により多くの意味を伝えることができます。

于 2013-01-14T00:29:47.730 に答える
35

この警告によって指摘されたコーディング エラーを作成しました。簡単な例:

fun x xs = go xs
  where
    go []      = ... 
    go (y:xs') = f y (go xs)

もちろん、再帰呼び出しにはxs'引数が必要であり、「定義されているが使用されていません」という警告がそれをキャッチします。私にとっては、未使用の一致に _ を使用する不便さは価値があります。

コンパイラはユーザーの意図を推測できません。別の一致で引数を使用したという事実は、警告を生成する一致でその引数を使用するつもりがなかったことを意味するものではありません。結局のところ、 を使用できtreeたので、使用しなかったという警告は妥当です。

ベンによる回答も参照してください_name。名前を使用するために使用できますが、それでも警告を抑制できます。

于 2013-01-13T23:46:53.017 に答える
9

コンパイラは、特定のスタイルのコーディングを使用することを提案しようとしています。それが気に入らない場合 (当然ですが)、問題を回避する方法があります。例を参照してください:

[一時的に]「定義されているが使用されていない」警告を抑制する方法は?

問題の内容について (これが有用な警告であるかどうかにかかわらず): このような状況で変数に名前を付けることの欠点は、名前がコンパイラーにとって意味のあるものではない場合でも、意味があることを示唆していることです。あなたが正しく指摘しているように、利点は、それら人間にとって意味があるということです. 基本的にトレードオフがあり、それはかなり主観的です。重要なことは、必要に応じて、必要な動作を取得できることです。

于 2013-01-13T23:24:57.373 に答える