7.2. 警告と整合性検査¶
GHC では,いくつものオプションを使って,コンパイル中の致命的ではないエラーに対して, どのようなメッセージ(警告ともいいます)を生成するかを選択できます. デフォルトでは,プログラム中のバグを示していることが多い以下の警告が有効になっています.
以下のフラグは標準的な警告の「詰め合せ」を簡単に選択するためのものです.
-
-W
標準の警告に加えて以下を有効にします.
-
-Wcompat
当面の間はデフォルトでは無効になっていますが,将来,デフォルトで有効になる予定の警告を有効にします. このフラグを有効にするとこで,ライブラリの作者は,警告を出さずに,新しい機能との互換性を確保しやすくなります.
これで有効になるのは,現時点では以下の警告です.
-
-Werror
すべての警告を致命的エラーにします.これを有効にすると,一括コンパイルのときに警告を見逃さずにすみます.
警告が発行されると,それを制御する警告フラグが何かも表示されます.
-
-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
も参照してください.
-
-Wpartial-type-signatures
部分型シグネチャ中にホールがあることをコンパイラが警告として報告するかを決定します.
-XPartialTypeSignatures
が有効になってい場合に限り効果があります. この言語拡張は型中のホールに関してエラーにするかどうかを制御します. Partial Type Signatures を参照してください.この警告はデフォルトで有効になっています.
-
-fhelpful-errors
名前やパッケージが有効範囲になければ,意図していたと推測した名前やパッケージを提案します.
このオプションはデフォルトで有効になっています.
-
-Wunrecognised-pragmas
GHC が認識できないプラグマが使われたときに警告を発します. GHC 自身が使うプラグマだけではなく,他のツールが使うことが判っているプラグマも認識します. たとえば
OPTIONS_HUGS
やDERIVE
がそれにあたります.このオプションはデフォルトで有効になっています.
-
-Wmissed-specialisations
-
-Wall-missed-specialisations
GHC が多重定義された関数を特定化できない場合に警告を発します. 通常そのような関数は
INLINEABLE
プラグマが必要だからです. 「all」付きの形式で指定した場合は,そうなる状況すべてを報告します. 「all」が付かない形式ではインポートされた関数の特定化過程で起りうる状況についてのみ報告します.「all」が付かない形式は(おそらく特定化可能であるということで)
INLINEABLE
がついたインポートされた関数が, 特定化されていない別の関数を呼んでいるために,特定できないという場合を捕捉するためのものです.これらの警告は
-Werror
を使ってもエラーにはならないことに注意してください.これらのオプションはデフォルトでは無効です.
-
-Wwarnings-deprecations
WARNING
あるいはDEPRECATED
プラグマの付いたモジュール,関数,型を使ったときに警告を発行します. 対応するプラグマについて詳しくは WARNING and DEPRECATED pragmas を参照してください.このオプションはデフォルトで有効です.
-
-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
が含まれるようになったときに,衝突を引き起す定義に対して警告を出します.Monoid
のインスタンスは,Semigroup
のインスタンスでもなければなりません.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
以下の場合に警告を発行します.
- データ型
T
をT(..)
のようにすべての構成子付きでインポートしているのに,その型が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``型の値に変換しようとしている場合に,コンパイラが警告を発行するようになります. このような呼び出しは何もしないのと同じで省略できます. 検査される関数は ``toInteger
,toRational
,fromIntegral
,realToFrac
です.
-
-Wimplicit-prelude
Preludeが暗黙に(インポート宣言なしで)インポートされる場合にコンパイラが警告を発行するようにします. Prelude の暗黙のインポートは
import ... Prelude ...
というインポート宣言で明示的にインポートされている場合や, 暗黙のインポートが(-XNoImplicitPrelude
あるいはLANGUAGE NoImplicitPrelude
プラグマにより)無効になっている場合を除きいつでも起ります.Preludeを暗黙に参照する構文に対して警告が出るわけではありません.
-XNoImplicitPrelude
によって Preludeを参照するかどうかが変化するような場合でも警告は出ません. たとえば368
はPrelude.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
以下の関数
f
はBar
に適用すると失敗します.-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つめのパターンが重なっているからです. 冗長なパターンはプログラマの誤りであることが,そうでないことよりも多いので,このオプションはデフォルトで有効になっています.
-
-Wtabs
コンパイラはソースファイルにタブ文字が含まれていると警告をだします.
-
-Wtype-defaults
数値型に対するデフォルト化機構が発動したときに警告/通知します. これは,あるデフォルトを前提としたコードを別のデフォルトの下のコードに変換するときに便利な情報です. たとえば
1
という値に特に制約がなければ,Haskell 1.4 の「デフォルトのデフォルト」では,これはInt
型ですが,Haskell 98 ではInteger
です. この違いは実行性能と挙動に影響を与える可能性があるので,通知があると便利です.この警告はデフォルトでは無効です.
-
-Wmonomorphism-restriction
単相性制限が適用される Haskell のコードがあるとコンパイラがそれを警告/通知します. 単相性制限が暗黙に適用されると予期せぬ振る舞いになる可能性がある場合には,単相性制限が適用されたことを明示的に警告してくれると便利です.
この警告はデフォルトで無効です.
-
-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 = []
ではx
とy
が未使用と報告されます. この警告は変数がアンダースコアで始まる変数の場合,すなわち以下のような場合には抑制されます.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-variables
は-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 を参照してください.
強く固執したいなら -dcore-lint
オプションを使う手もあります.
このオプションでは GHC 内部のパスで強力な整合性検査を行ないます(GHC の整合性検査であって,プログラマの整合性検査ではありませんよ).