patterns vs. guards: otherwise does not match?
The following two functions behave differently when given an empty string:
guardMatch l@(x:xs)
| x == '-' = "negative " ++ xs
| otherwise = l
patternMatch开发者_StackOverflow社区 ('-':xs) = "negative " ++ xs
patternMatch l = l
Here my output:
*Main> guardMatch ""
"*** Exception: matching.hs:(1,1)-(3,20): Non-exhaustive patterns in function guardMatch
*Main> patternMatch ""
""
Question: why does not the 'otherwise' close catch the empty string?
The otherwise
is within the scope of the pattern l@(x:xs)
, which can only match a non-empty string. It might help to see what this (effectively) translates to internally:
guardMatch l = case l of
(x :xs) -> if x == '-' then "negative " ++ xs else l
patternMatch l = case l of
('-':xs) -> "negative " ++ xs
_ -> l
(Actually, I think the if
is translated to a case
+ guard instead of the other way around.)
A guard is always evaluated after the pattern. This is - the guard is tried iff the pattern succeeds. In your case, the pattern (x:xs)
excludes the empty string, so the guards are not even tried, as the pattern fails.
The other two answers are totally right of course, but here's another way to think about it: What if you had written this?
guardMatch l@(x:xs)
| x == '-' = "negative " ++ xs
| otherwise = [x]
What would you expect guardMatch ""
to be?
精彩评论