7.2. 警告と整合性検査

GHC では,いくつものオプションを使って,コンパイル中の致命的ではないエラーに対して, どのようなメッセージ(警告ともいいます)を生成するかを選択できます. デフォルトでは,プログラム中のバグを示していることが多い以下の警告が有効になっています.

以下のフラグは標準的な警告の「詰め合せ」を簡単に選択するためのものです.

-W

標準の警告に加えて以下を有効にします.

-Wall

疑わしいコードであることを示しうるすべての警告オプションを有効にします. -Wall有効にならない 警告は以下のものです.

-Wcompat

当面の間はデフォルトでは無効になっていますが,将来,デフォルトで有効になる予定の警告を有効にします. このフラグを有効にするとこで,ライブラリの作者は,警告を出さずに,新しい機能との互換性を確保しやすくなります.

これで有効になるのは,現時点では以下の警告です.

-Wno-compat

-Wcompat で有効になる警告をすべて無効にします.

-w

標準警告に含まれないもの -Wall が有効にしないものを含めて,すべての警告を無効にします.

以下のオプションでは,警告をすべて致命的なものとみなし,コンパイルを中断します.

-Werror

すべての警告を致命的エラーにします.これを有効にすると,一括コンパイルのときに警告を見逃さずにすみます.

-Werror=⟨wflag⟩
Implies:-W<wflag>

指定した警告を致命的エラーにします.これを指定しない警告はそのまま警告として使えます.

-Wwarn

警告を警告として扱い,エラーにはしません.これはデフォルトですが, -Werror フラグを否定するのに便利です.

-Wwarn=⟨wflag⟩

指定した警告を警告として扱い,エラーにはしません.

-Werror=<wflag> を完全に否定するものではなく,警告としてそのまま使えます.

警告が発行されると,それを制御する警告フラグが表示されます.

-fshow-warning-groups

どのフラグがその警告を制御しているかを表示する際, その警告を含む警告フラググループについても表示します.

このオプションはデフォルトでは有効になっていません.

以下に警告オプションのすべてを説明します. なんらかの警告を無効にしたい場合には,その警告に対応する -Wno-... というオプションをコマンドラインで指定するといいでしょう. いまのところ GHC 8.0 よりも前のバージョンとの後方互換性のために,すべての警告は -W(no-)* でなくても -f(no-)warn-* ででも制御できます.

-Wunrecognised-warning-flags

認識できない -W... フラグをコンパイラに指定したことを警告します.

この警告はデフォルトで有効になっています.

-Wtyped-holes

コンパイラが型付きホールの警告を出すかを決めます. 型付きホールのエラーがランタイムまで遅延されているときにのみ効果があります. Typed Holes および Deferring type errors to runtime を参照してください.

この警告はデフォルトで有効になっています.

-Wtype-errors

型エラーが実行時まで遅延されているときに警告を出します. Deferring type errors to runtime を参照してください.

この警告はデフォルトで有効になっています.

-fdefer-type-errors
Implies:-fdefer-typed-holes

可能なかぎり多くの型エラーを実行時まで引き延ばします. コンパイル時にはエラーではなく警告がでます. 実行時には,型エラーを起こす変数を使ったときに実行時エラーになります. しかし,型が正しい部分については,正しく動きます. Deferring type errors to runtime を参照してください.

-fdefer-typed-holes

型付きホールのエラー(アンダースコアで始まる名前(たとえば __foo_bar)に関するエラー)を実行時まで遅延します. これは typed holes によって起きたエラーを警告にします. 型付きホールに依存する値を使うと -fdefer-type-errors (これを指定すると -fdefer-typed-holes が有効になる)のときと同じく実行時エラーになります. Typed Holes および Deferring type errors to runtime を参照してください.

-fdefer-type-errors によって有効になります. -Wtyped-holes も参照してください.

-fdefer-out-of-scope-variables

変数の有効範囲外エラー(アンダースコアで始まらない名前に関するエラー)を実行時まで遅延します. これは変数の有効範囲外エラーを警告に換えるものです. 有効範囲外の変数に依存する値を使うと -fdefer-type-errors (これを指定すると -fdefer-out-of-scope-variables`が有効になる)のときと同じく実行時エラーになります. :ref:`typed-holes および Deferring type errors to runtime を参照してください.

-fdefer-type-errors によって有効になります. -Wdeferred-out-of-scope-variables も参照してください.

-Wdeferred-out-of-scope-variables

有効範囲外エラーが遅延されている変数に対して警告を出します.

-Wpartial-type-signatures

部分型シグネチャ中にホールがあることをコンパイラが警告として報告するかを決定します. -XPartialTypeSignatures が有効になってい場合に限り効果があります. この言語拡張は型中のホールに関してエラーにするかどうかを制御します. Partial Type Signatures を参照してください.

この警告はデフォルトで有効になっています.

-fhelpful-errors

名前やパッケージが有効範囲になければ,意図していたと推測した名前やパッケージを提案します.

このオプションはデフォルトで有効になっています.

-Wunrecognised-pragmas

GHC が認識できないプラグマが使われたときに警告を発します. GHC 自身が使うプラグマだけではなく,他のツールが使うことが判っているプラグマも認識します. たとえば OPTIONS_HUGSDERIVE がそれにあたります.

このオプションはデフォルトで有効になっています.

-Wmissed-specialisations
-Wall-missed-specialisations

GHC が多重定義された関数を特定化できない場合に警告を発します. 通常そのような関数は INLINEABLE プラグマが必要だからです. 「all」付きの形式で指定した場合は,そうなる状況すべてを報告します. 「all」が付かない形式ではインポートされた関数の特定化過程で起りうる状況についてのみ報告します.

「all」が付かない形式は(おそらく特定化可能であるということで) INLINABLE がついたインポートされた関数が, 特定化されていない別の関数を呼んでいるために,特定できないという場合を捕捉するためのものです.

これらの警告は -Werror を使ってもエラーにはならないことに注意してください.

これらのオプションはデフォルトでは無効です.

-Wwarnings-deprecations

WARNING あるいは DEPRECATED プラグマの付いたモジュール,関数,型を使ったときに警告を発行します. 対応するプラグマについて詳しくは WARNING and DEPRECATED pragmas を参照してください.

このオプションはデフォルトで有効です.

-Wdeprecations

WARNING あるいは DEPRECATED プラグマの付いたモジュール,関数,型を使ったときに警告を発行します. 対応するプラグマについて詳しくは WARNING and DEPRECATED pragmas を参照してください. これは -Wwarnings-deprecations の別名です.

このオプションはデフォルトで有効です.

-Wamp

このオプションは廃止予定で非推奨です.

AMP (Applicative-Monad proosal)と衝突する定義があった場合に警告を発行します.

-Wnoncanonical-monad-instances

非標準の Applicative あるいは Monad インスタンス宣言を検出した場合に警告を発行します.

この警告が有効になっている場合は,以下の条件を確認します.

Monad のインスタンス宣言において,以下の条件が満たされていなければ警告になります.

  • return が定義されているなら,標準的定義(すなわち return = pure)でなければならない.
  • (>>) が定義されているなら,標準的定義(すなわち (>>) = (*>))でなければならない.

さらに Applicative のインスタンス定義においては,

  • pure が逆方向定義(すなわち pure = return) であれば警告します.
  • (*>) が逆方向定義(すなわち (*>) = (>>))であれば警告します.

このオプションはデフォルトでは無効です.

-Wnoncanonical-monadfail-instances

Monad あるいは MonadFail のインスタンス宣言が標準的ではない場合に警告を発行します.

この警告が有効になっている場合は,以下の条件を確認します.

Monad のインスタンス宣言において,以下の条件が満されていなければ警告になります.

  • fail が定義されているなら,標準的定義(すなわち fail = Control.Monad.Fail.fail)でなければならない.

さらに MonadFail のインスタンス定義においては,

  • fail が逆方向定義(すなわち fail = Control.Monad.fail)であれば警告します.

-Wmissing-monadfail-instances も参照してください.

このオプションはデフォルトでは無効です.

-Wnoncanonical-monoid-instances

Semigroup あるいは Monoid のインスタンス宣言が標準的でないときに警告を発行します.

この警告が有効になっている場合は,以下の条件を確認します.

Monoid のインスタンス宣言において,以下の条件が満たされていなければ警告になります.

  • mappend が定義されているなら,標準的定義(すなわち mappend = (Data.Semigroup.<>))でなければならない.

さらに Semigroup のインスタンス宣言において

  • (<>) が逆方向定義(すなわち (<>) = mappend)であれば警告します.

この警告はデフォルトでは無効になっています.しかし,この警告は -Wcompat というオプショングループに属しています.

-Wmissing-monadfail-instances

do ブロックで失敗する可能性のあるパターンが用いられていて MonadFail のインスタンスではないときに警告を発行します.

-Wnoncanonical-monadfail-instances も参照してください.

この警告フラグは -Wcompat というオプショングループに属していていますが, デフォルトでは無効になっています.しかし,将来のリリースでは MonadFail Proposal (MFP) の一部としてデフォルトで有効になる予定です.

-Wsemigroup

将来,標準の型クラスに Semigroup が含まれるようになったときに,衝突を引き起す定義に対して警告を出します.

  1. Monoid のインスタンスは,Semigroup のインスタンスでもなければなりません.
  2. Semigroup の演算子 (<>)Prelude に入る予定ですので,このような演算子を独自に定義しているとクラッシュします.

このフラグは -Wcompat オプショングループに属しています.デフォルトでは無効になっていますが, 将来の GHC のリリースでは,デフォルトで有効になります.

-Wdeprecated-flags

非推奨になっているコマンドラインを使っていると警告を発行します.

このオプションはデフォルトで有効です.

-Wunsupported-calling-conventions

サポートされていない呼び出し方法を外部宣言で用いると警告を発行します. 具体的には stdcall という呼び出し方法を i386 以外のアーキテクチャ上のシステムで使うと ccall として扱います.

-Wdodgy-foreign-imports

以下の形式の外部インポートに対して警告を発行します.

foreign import "f" f :: FunPtr t

おそらく

foreign import "&f" f :: FunPtr t

と書くべきだったと思われます. 1つめの形式では `f` は(純粋な) C の関数で,引数はとらず,型 `t` の C の関数へのポインタを宣言しています. 1つめの宣言は通常は誤りで,クラッシュにつながりデバッグのしにくいバグになるので,この警告が用意されています.

-Wdodgy-exports

型シノニムにすぎないデータ型 T がすべての構成子を T(..) のようにエクスポートしているときに警告を発行します.

また,何もエクスポートしていないモジュールを再エクスポートしているときも警告を発行します.

-Wdodgy-imports

以下の場合に警告を発行します.

  • データ型 TT(..) のようにすべての構成子付きでインポートしているのに,その型が T のように 抽象的にしかエクスポートされていない場合.
  • import 宣言がエクスポートされていない実体を隠蔽している場合.
-Woverflowed-literals

リテラルがオーバーフローを起こすような場合,たとえば 300 :: Word8 のような場合に警告を発行します.

-Wempty-enumerations

たとえば [5 .. 3] のように列挙が空になる場合に警告を発行します.

-Wduplicate-constraints

型シグネチャで制約の重複がある場合コンパイラが警告を発行するようにします. たとえば,以下のような場合です.

f :: (Eq a, Show a, Eq a) => a -> a

この警告では Eq a という制約が重複していることを表示します.

このオプションは -Wredundant-constraints があるので,非推奨になっています.

-Wredundant-constraints
Since:8.0

型シグネチャで冗長な制約がある場合にコンパイラが警告を発行するようにします. 具体的には,

  • 型シグネチャ内に冗長な制約がある場合.

    f :: (Eq a, Ord a) => a -> a
    

    この警告では Eq a という警告が冗長であることが表示されます. Ord a 制約によって Eq a 制約は仮定済みになるからです.

  • 型シグネチャ内の制約がカバーする範囲のコードで,その制約が使われていない場合.

    f :: Eq a => a -> a -> Bool
    f x y = True
    

    この警告では Eq a という制約が冗長であることが示されます. (この制約は f の定義で使われていません.)

インスタンス宣言中に冗長な制約がある場合についても同様の警告がでます.

このオプションはデフォルトで有効です. 通常どおり -Wno-redundant-constraints を使えば,モジュール毎にこの警告を抑制できます. 必要とされる以上の制約を加えた型シグネチャを書きたい場合には,APIを変更することなく,実装を変更する余地が残されています. そのような場合には,使われない束縛を使って,関数ごとに警告を抑制できます. たとえば,以下のようにします.

f :: Eq a => a -> a -> Bool
f x y = True
where
    _ = x == x  -- (Eq a)に対する冗長な制約警告を抑制

ここでは (==) を呼び出すことで,GHC は (Eq a) という制約が必要であると判断しますので,警告は発行されません.

-Wduplicate-exports

エクスポートリストに重複したエントリがある場合にコンパイラが警告を発行するようにします. この機能は大きなエクスポートリストを保守するのに便利です. 削除したはずのエクスポートリストのエントリがエクスポートされつづけるというようなことを避けられます.

このオプションはデフォルトで有効です.

-Whi-shadowing

現在のディレクトリにあるモジュールやインターフェイスファイルが,ライブラリや別のディレクトリにある同名のモジュールをシャドーイングしてしまっている場合,コンパイラが警告を発行するようになります.

-Widentities

Prelude の数値変換が T 型の値を同じ T 型の値に変換しようとしている場合に,コンパイラが警告を発行するようになります. このような呼び出しは何もしないのと同じで省略できます. 検査される関数は toIntegertoRationalfromIntegralrealToFrac です.

-Wimplicit-prelude

Preludeが暗黙に(インポート宣言なしで)インポートされる場合にコンパイラが警告を発行するようにします. Prelude の暗黙のインポートは import ... Prelude ... というインポート宣言で明示的にインポートされている場合や, 暗黙のインポートが(-XNoImplicitPrelude あるいは LANGUAGE NoImplicitPrelude プラグマにより)無効になっている場合を除きいつでも起ります.

Preludeを暗黙に参照する構文に対して警告が出るわけではありません. -XNoImplicitPrelude によって Preludeを参照するかどうかが変化するような場合でも警告は出ません. たとえば 368Prelude.fromInteger (368::Prelude.Integer) という意味であっても警告はでないということに注意してください. ここで Prelude はコンパイル中のモジュールが何をインポートしているかにかかわらず,実際のPreludeモジュールを参照します.

この警告はデフォルトでは無効です.

-Wincomplete-patterns
-Wincomplete-uni-patterns

-Wincomplete-patterns はパターン照合が実行時に失敗する可能性がある場合に警告を発行します. 以下の関数 g は空ではないリストに適用すると失敗するので -Wincomplete-patterns が有効ならコンパイラは警告を発行します.

g [] = 2

このオプションは小うるさいことがあり,また常にバグを示しているわけもないので,デフォルトでは有効になっていません. しかし,関数を定義するときにはすべての場合を網羅するのが一般的に良い習慣です. このオプションは -W で有効になります.

-Wincomplete-uni-patterns というフラグは,単一パターンしか許されない構文要素,つまりλ抽象式およびパターン束縛にのみ適用されるという点を除けば -Wincomplete-patterns と同じである.

h = \[] -> 2
Just k = f y
-fmax-pmcheck-iterations=⟨n⟩
Default:2000000

パターン照合検査器が諦めるまでの反復回数を設定します. この制限はパターン照合が(一般的な場合の検査範囲のカバー率が指数オーダーになるなど)極端にコストがかかるような場合を捕捉するためのものです. GHC がパターン照合検査器の反復限界を超えたと報告しないかぎり,通常は設定する必要はありません. (そのような場合には,将来そのコードを読む人のために,パターン照合の部分のリファクタリングを考えることになるでしょう.)

-Wincomplete-record-updates

以下の関数 fBar に適用すると失敗します. -Wincomplete-record-updates を有効にしておくと,この場合に警告が発行されます.

data Foo = Foo { x :: Int }
         | Bar

f :: Foo -> Foo
f foo = foo { x = 6 }

このオプションは小うるさく,プログラムのバグを示さないことも多いので,デフォルトでは有効になっていません.

-Wmissing-fields

このオプションはデフォルトで有効です. ラベル付きフィールド構成子を構成するときに,1つ以上のフィールドについて初期化子が欠如している場合に警告を発行します. これはエラーではありません(省略されたフィールドはボトムで初期化されます)が,多くの場合プログラムに誤りがあることを示します.

-Wmissing-import-lists

qualified ではない import 宣言で,スコープに持ち込む実体を明示的に列挙していないインポート宣言に対して警告を発行する. たとえば

module M where
  import X( f )
  import Y
  import qualified Z
  p x = f x x

-Wmissing-import-lists フラグが有効なら Y のインポートに対して警告が発行されます. X については警告はでません. 後から Y がたとえば f をエクスポートするように変更されると M の中での f への参照は曖昧になってしまいます. Z のエクスポートを拡張しても M で曖昧な部分ができる可能性は低いので Z をインポートすることについては警告はでません.

-Wmissing-methods

このオプションはデフォルトで有効です. インスタンス宣言が1つ以上のメソッドを欠き,そのメソッドのデフォルト定義が対応するクラス宣言にないときに警告を発行します.

メソッド名がアンダースコアで始まっているときにはこの警告はでません. このことは以下のような場合に便利です.

class C a where
    _simpleFn :: a -> String
    complexFn :: a -> a -> String
    complexFn x y = ... _simpleFn ...

基本的な考え方は (a) クラスの利用者はもっぱら complexFn を呼び _simpleFn を呼ぶことはなく,かつ, (b) インスタンス宣言では complexFn_simpleFn のどちらか一方を定義すればよいということです.

MINIMAL プラグマを使うと,特定のクラスに対して,どのメソッドの組み合わせが要求されるかを変更できます. 詳しくは MINIMAL pragma を参照してください.

-Wmissing-signatures

どのトップレベルの関数や値にも型シグネチャがあることを GHC に確認させたければ, -Wmissing-signatures オプションを使うのがよいでしょう. GHC はこの警告の一部として,推論できた型を報告します. このオプションはデフォルトでは無効になっています.

-Wmissing-exported-sigs

このオプションは -Wmissing-exported-signatures があるので,非推奨となっています.

-Wmissing-exported-signatures

エクスポートされるどのトップレベルの関数や値にも型シグネチャがあることを GHC に確認させ, エクスポートしないトップレベルの関数や値については確認しないということをしたければ -Wmissing-exported-signatures オプションを使うのが良いでしょう. このオプションは -Wmissing-signatures より優先されます. この警告の一部として GHC は推論できた型を報告します. このオプションはデフォルトでは無効になっています.

-Wmissing-local-sigs

このオプションは -Wmissing-local-signatures があるので,非推奨となっています.

-Wmissing-local-signatures

-Wmissing-local-signatures を使えば,GHC はあらゆる多相的な局所束縛について警告を発行するようになります. 警告の一部として,GHC は推論できた型を報告します. このオプションはデフォルトでは無効です.

-Wmissing-pattern-synonym-signatures

どのパターンシノニムにも型シグネチャがあることを GHC に確認させたければ, -Wmissing-pattern-synonym-signatures オプションを使うのが良いでしょう. オプションを -Wmissing-exported-signatures と同時に使えば,エクスポートするパターンシノニムだけが型シグネチャを付けなければならなくなります. 警告の一部として,GHC は推論できた型も報告します. このオプションはデフォルトでは無効になっています.

-Wname-shadowing

このオプションを有効にすると,内側のスコープの値と同じ名前の値が外側のスコープにあるとき, すなわち,内側の名前が外側の名前を隠す(シャドウする)ときに警告を発行する. この警告によって,ミスタイプによる見つけにくいバグを捕捉できることがある. たとえば f = ... let f = id in ... f ... において,再帰呼び出しであるはずのものがそうなっていないことが捕捉されます.

この警告は,以下のようにアンダースコアで始まる名前については発行されません.

f x = do { _ignore <- this; _ignore <- that; return (the other) }
-Worphans

このフラグが有効なら,モジュールに「孤立した」インスタンス宣言あるいは書き換え規則があるときに警告を発行します. インスタンス宣言が孤立しているとは,インスタンス宣言があるモジュールに,対応するクラスも具体化された型も定義されていないということです. 書き換え規則が孤立しているとは,別のモジュールで宣言されている関数に対する規則であるということです. 孤立したインスタンス宣言や書き換え規則を含むモジュールを孤立モジュールと呼びます.

孤立インスタンスや孤立規則の問題は,インスタンスや規則が役割を果さなければならない場合にそなえて, 他には何の役に立たなくても GHC はすべての孤立モジュールに対するインターフェイスファイルを積極的に読み込んでおかなければならないことです. 詳細については Orphan modules and instance declarations を参照してください.

この -Worphans フラグは,ユーザが書いた孤立インスタンスや孤立規則について警告をだします.

-Woverlapping-patterns

デフォルトで,コンパイラはパターンが重複しているときに警告を発行します. 例をあげると

f :: String -> Int
f []     = 0
f (_:xs) = 1
f "2"    = 2

ここで f の最後のパターン照合に至ることは決してありません. 2つめのパターンが重なっているからです. 冗長なパターンはプログラマの誤りであることが,そうでないことよりも多いので,このオプションはデフォルトで有効になっています.

-Wsimplifiable-class-constraints
Since:8.2

トップレベルのインスタンス宣言を使用して簡略化できる型シグネチャのクラス制約について警告します. たとえば

f :: Eq [a] => a -> a

においては,シグネチャ内の Eq [a]Eq a のトップレベルインスタンスとオーバーラップしています. GHCは前者を使おうとしますが,後者を使う場面で Eq a は解決できない制約になってしまいます. これを避ける最善の方法は

f :: Eq a => a -> a

と書くことです. このオプションはデフォルトで有効になっています. 通常と同じくモジュール単位でこれらを抑制するには -Wno-simplifiable-class-constraints を使います.

-Wtabs

コンパイラはソースファイルにタブ文字が含まれていると警告をだします.

-Wtype-defaults

数値型に対するデフォルト化機構が発動したときに警告/通知します. これは,あるデフォルトを前提としたコードを別のデフォルトの下のコードに変換するときに便利な情報です. たとえば 1 という値に特に制約がなければ,Haskell 1.4 の「デフォルトのデフォルト」では,これは Int 型ですが,Haskell 98 では Integer です. この違いは実行性能と挙動に影響を与える可能性があるので,通知があると便利です.

この警告はデフォルトでは無効です.

-Wmonomorphism-restriction

単相性制限が適用される Haskell のコードがあるとコンパイラがそれを警告/通知します. 単相性制限が暗黙に適用されると予期せぬ振る舞いになる可能性がある場合には,単相性制限が適用されたことを明示的に警告してくれると便利です.

この警告はデフォルトで無効です.

-Wunsupported-llvm-version

-fllvm フラグでサポートされていないバージョンの LLVM を使おうとすると警告がでます.

-Wunticked-promoted-constructors

昇格したデータ構成子をアポストロフィの前置なしに使うと警告を出します.

例をあげると

data Nat = Succ Nat | Zero

data Vec n s where
  Nil  :: Vec Zero a
  Cons :: a -> Vec n a -> Vec (Succ n) a

これは Zero および Succ がそれぞれ 'Zero および 'Succ と書いていないので2箇所で警告がでます.

この警告は -Wall モードではデフォルトで有効になっています.

-Wunused-binds

未使用の関数定義(および局所的な束縛)をすべて報告します. 以下のフラグを3つとも指定するの同じことになります.

-Wunused-top-binds

未使用の関数定義をすべて報告します.

より正確にいうと,有効範囲に束縛によって持ち込まれた変数が未使用で,かつ,その変数名がアンダースコアで始まっていないときに警告がでます. この「アンダースコアで始まる」という条件のおかげで,選択的にこの警告を無効にできます.

変数が使用されているとは以下の場合です.

  • エクスポートされている場合,または
  • すくなくとも1つの使用されている変数を束縛する右辺に現れている場合

以下に例をあげます.

module A (f) where
f = let (p,q) = rhs1 in t p  -- 無警告: q は未使用ですが,局所的な束縛です.
t = rhs3                     -- 無警告: f は使用されており,したがって,t も使用されています.
g = h x                      -- 警告: g は未使用です.
h = rhs2                     -- 警告: h は他の未使用束縛の右辺でしか使われていません.
_w = True                    -- 無警告: _w はアンダースコアで始まっています.
-Wunused-local-binds

未使用の局所定義をすべて報告します.たとえば以下のとおりです.

module A (f) where
f = let (p,q) = rhs1 in t p  -- 警告: q は未使用です.
g = h x                      -- 無警告: g は未使用ですが,トップレベルの束縛です.
-Wunused-pattern-binds

パターン束縛が変数を1つも束縛しないときに警告がでます. ただし,単独のワイルドカード(バン付きも含む)のときは警告を出しません. 以下はその例です.

Just _ = rhs3    -- 警告: 未使用パターン束縛
(_, _) = rhs4    -- 警告: 未使用パターン束縛
_  = rhs3        -- 無警告: 単独ワイルドカードパターン
!_ = rhs4        -- 無警告: バン付き単独ワイルドカードパターン,seq と同じ効果があります.

単独のワイルドカードパターンを許容するのは,警告が出ない _v = rhs3 と大して違いはないからです. また,このようなパターンは型に対する制約を加えるのに便利だからです.たとえば _ = x::Int のように使えます. 単独のバン付きワイルドカードパターンは評価を強制する seq の代替として便利です.

-Wunused-imports

明示的にインポートされながら,使われていないモジュールをすべて報告します. ただし import M() という形式のインポートについては未使用インポートとしては報告しません. これはインスタンス宣言(Haskell では無名)をインポートするための有用なイディオムだからです.

-Wunused-matches

項レベルパターン照合で発生する未使用変数をすべて報告します. これには,単一の変数から構成されるパターンも含まれます. たとえば f x y = [] では xy が未使用と報告されます. この警告は変数がアンダースコアで始まる変数の場合,すなわち以下のような場合には抑制されます.

f _x = True

-Wunused-matches では型族やデータ族のインスタンスに見られるようなトップレベルパターンの変数については警告を出しません. このような場合に警告を出すようにするには,別に -Wunused-type-patterns フラグを有効にしなければなりません.

-Wunused-do-bind

do および mdo ブロックで情報を黙って捨てているように見える式を報告します. たとえば do { mapM popInt xs ; return 10 } の場合 do ブロックの最初の文があやしいと報告されます. 型は StackM [Int] であって StackM () ではないにもかかわらず [Int] 型の値は何も束縛しないからです. この警告は,何かを捨てていることをプログラム中で明示的に示せば抑制されます.

do { _ <- mapM popInt xs ; return 10 }

もちろん場合によってはもっと良い方法があります.

do { mapM_ popInt xs ; return 10 }
-Wunused-type-patterns

型族およびデータ族のインスタンスで発生する未使用型変数をすべて報告します.たとえば

type instance F x y = []

では x および y が未使用と報告されます. この警告は,型変数名がアンダースコアで始まる場合,たとえば,以下のような場合には抑制されます.

type instance F _x _y = []

-Wunused-matches とは違い -Wunused-type-patterns-Wall によって有効になることはありません. このようにしてある論拠は,項レベルパターン名とは違い,型名はドキュメントとして意味のある名前が選ばれるからで, アンダースコアを付ける(ように仕向ける)と読み難いものになってしまうからです.

-Wunused-foralls

ユーザが明示的に書いた forall 文にある未使用型変数をすべて報告する.たとえば

g :: forall a b c. (b -> b)

の場合は a および c が未使用として報告される.

-Wwrong-do-bind

do および mdo ブロックの中で,束縛を欠いているように見える式を報告します. たとえば do { return (popInt 10) ; return 10 } の場合 do ブロックにおいて1つめの文は怪しいと報告されます. 型は StackM (StackM Int) (同じモナド構成子を2重に適用しています)ですが,結果で束縛することで「解かれて」いません. この警告は,結果を捨てるように明示するコードを書くことで抑制できます.

do { _ <- return (popInt 10) ; return 10 }

ほとんどのまともなプログラムでは,このような部分はバグであることを示しています. 意図はおそらく以下のようになコードでしょう.

do { popInt 10 ; return 10 }
-Winline-rule-shadowing

関数がインライン展開されてしまって,書き換え規則が発火できない場合に警告を出します. How rules interact with INLINE/NOINLINE pragmas を参照してください.

-Wcpp-undef

このフラグは -Wundef をCプリプロセッサ(使用されている場合)に渡します. これにより,プリプロセッサは未定義の識別子に対して #if 指示文を使用していると警告します.

-Wunbanged-strict-patterns

このフラグは,リフトされていない型の値による束縛が起るようなパターンで, バンパターンでも裸の変数でもない場合に警告します. リフトされていない型の情報については Unboxed types を参照してください.

-Wmissing-home-modules
Since:8.2

現在コンパイルされているパッケージ(すなわち「ホーム」パッケージ)によって提供されるモジュールがインポートされるていても, コマンドラインでターゲットとしてに明示的にリストされていないときに警告します. Cabal で GHCが exposed-modules にも other-modules にもリストされていないモジュールを取り上げないようにするのに役立ちます.

強く固執したいなら -dcore-lint オプションを使う手もあります. このオプションでは GHC 内部のパスで強力な整合性検査を行ないます(GHC の整合性検査であって,プログラマの整合性検査ではありませんよ).