Templates vs security guards: otherwise not consistent?

The following two functions behave differently when specifying an empty string:

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

Here is my conclusion:

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

Question: why the empty line is not closed "otherwise"?

+4
source share
3 answers

otherwise is in the area of ​​the template l@ (x:xs) , which can only match a non-empty string. This can help to see what this (effectively) translates into 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 that if translates to case + guard, not the other way around).

+13
source

The guard is always evaluated after the pattern. This protection is checked if the template succeeds. In your case, the pattern (x:xs) excludes the empty string, so the guards did not even try, because the pattern does not work.

+9
source

The other two answers are perfectly correct, but here is another way to think: what if you wrote this?

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

What do you expect from guardMatch "" ?

+3
source

All Articles