Mixing pattern matching and guards

Hello all, I recently wrote this piece of code import qualified Data.Set as S [...] purge :: (Eq cp, Eq ip) => Product cp ip -> Product cp ip purge (Punion ps) | ps' == S.empty = Pempty where ps' = S.filter (/= Pempty) ps purge x = x and I thought I had missed the "otherwise" case in the guard and I was prepared to see a "non exhaustive ..." error, but to my amazement it works *Main> purge $ Punion $ S.fromList [Packed 1 Pempty] Punion (fromList [Packed 1 Pempty]) As this is a Punion, it should match the first pattern, but not the guard. It seems to fall right through to the second pattern. Is this the way it works?

On Tue, Dec 22, 2015 at 06:29:32AM +0100, martin wrote:
Hello all,
I recently wrote this piece of code
import qualified Data.Set as S [...] purge :: (Eq cp, Eq ip) => Product cp ip -> Product cp ip purge (Punion ps) | ps' == S.empty = Pempty where ps' = S.filter (/= Pempty) ps purge x = x
and I thought I had missed the "otherwise" case in the guard and I was prepared to see a "non exhaustive ..." error, but to my amazement it works
The pattern does match (and any variable bound by it is made available to the corresponding guards). Then guards are tried in order: if no guard succeed, the next pattern match is found (in your case purge x = x, irrefutable). If you want you can add a catch all guard as last guard: | ps' == S.empty = Pempty | otherwise = undefined -- handle ps' /= S.empty here
participants (2)
-
Francesco Ariis
-
martin