2016-12-30 3 views
2

だから私はこのパターンにマッチさせようとしています。 MessageTypeは私が作成した型です。この関数は文字列を受け取り、その文字列の最初の文字に応じてMessageTypeを出力します。私もコンパイルするたびに、私は警告と言って出ます:パターンマッチングは非誇りです - 最終的なガードの私の「そうでなければ」は空のリストをどう扱わないのでしょうか?

Pattern match(es) are non-exhaustive 
    In an equation for ‘parseMessage’: Patterns not matched: [] 

は、ここに私のコードです:

parseMessage :: String -> MessageType 
parseMessage (x:_) 
    | x == 'I'  = Info 
    | x == 'W'  = Warning 
    | otherwise  = Error 1 

どのようにそれは私のパターンマッチが網羅的ではないということですか? otherwiseガードは他のものをキャッチしませんか?私の機能がどのようにすべての文字列を捕らえることができないのかわかりません。

このような関数を書くと、警告が出ません。

parseMessage []  = error "Empty String" 
parseMessage (x:_) = if x == 'I' 
         then Info 
         else if x == 'W' 
         then Warning 
         else Error 1 

私は警告が「パターンが一致していない:[]」と言うことを見たので、私はこの方法で私の機能を書き直したので、私は明示的にそれを処理していました。しかし、なぜ私の機能の最初のバージョンでは、パターンは処理されないと言われていますか? otherwiseは最初の2人の警備員のほかにすべてをキャッチしませんか?

答えて

12

ガードは、関数の定義の中の1つのパターンの場合に固有のものですので、あなたはこれを書くとき:

parseMessage (x:_) 
    | x == 'I'  = Info 
    | x == 'W'  = Warning 
    | otherwise  = Error 1 

...あなたはparseMessage ""を実行した場合、あなたの警備員にも相談されることはありません。 (x:_)パターンは失敗するため、ガードはすべて無視されます。 xがガード条件内でバインドされるためには、これが必要です。

parseMessage :: String -> MessageType 
parseMessage "" = Error 1 
parseMessage (x:_) 
    | x == 'I'  = Info 
    | x == 'W'  = Warning 
    | otherwise  = Error 1 

今、あなたは取り扱ってきたすべての可能な例:

は、この問題を解決するには、あなただけの空の文字列を扱う場合を追加する必要があります。直接書き込むないのはなぜ

+1

私は 'otherwise'句を取り除くだろう、とは最後に' parseMessage _ =エラーを1'追加します。 – dfeuer

+4

ああ、そうです。空の文字列は、リストの最初の要素をチェックするように設定した初期パターンのため、ガードによって捕捉されません。 –

8

...

parseMessage ('I':_) = Info 
parseMessage ('W':_) = Warning 
parseMessage _  = Error 1 
関連する問題