4

次の 2 つの関数は、空の文字列を指定すると動作が異なります。

guardMatch l@(x:xs) 
    | x == '-'        = "negative " ++ xs
    | otherwise       = l

patternMatch ('-':xs) = "negative " ++ xs
patternMatch l        = l

ここに私の出力:

*Main> guardMatch ""
"*** Exception: matching.hs:(1,1)-(3,20): Non-exhaustive patterns in function guardMatch

*Main> patternMatch ""
""

質問: 'otherwise' クローズが空の文字列をキャッチしないのはなぜですか?

4

3 に答える 3

13

otherwisepattern のスコープ内にあり、l@(x:xs)空でない文字列にのみ一致します。これが(効果的に)内部的に何に変換されるかを確認すると役立つ場合があります。

guardMatch   l = case l of
                   (x  :xs) -> if x == '-' then "negative " ++ xs else l
patternMatch l = case l of
                   ('-':xs) ->                  "negative " ++ xs
                   _        ->                                         l

(実際には、 は逆ではなく + ガードにif変換されていると思います。)case

于 2011-07-05T15:55:42.147 に答える
9

ガードは常にパターンの後に評価されます。これは - パターンが成功した場合にガードが試行されます。あなたの場合、パターン(x:xs)は空の文字列を除外するため、パターンが失敗するため、ガードは試行されません。

于 2011-07-05T15:56:15.063 に答える
3

もちろん、他の2つの答えは完全に正しいですが、それについて考える別の方法があります。これを書いたとしたらどうでしょうか。

guardMatch l@(x:xs) 
    | x == '-'        = "negative " ++ xs
    | otherwise       = [x]

あなたは何を期待guardMatch ""しますか?

于 2011-07-06T05:31:05.317 に答える