
While playing with some pattern guard code, I discovered some scoping behavior that I wasn't expecting. I learned that pattern guard bindings aren't visible in their equation's where clauses. To make this concrete, in the following (contrived) example, "test1" works, but "test2" complains that 'v' is unbound: data Bar = Baz Int | Biz Int | Empty toInt (Baz i) = Just i toInt (Biz i) = Just (2 * i) toInt Empty = Nothing test1 :: Bar -> Int test1 b | Just v <- toInt b = v + 1 test1 _ = 0 test2 :: Bar -> Int test2 b | Just v <- toInt b = k where k = v + 1 test2 _ = 0 From an implementation perspective, I understand the behavior as an artifact of desugaring pattern guards into a case expression. But, as a user, it seems like an odd restriction on how I organize my code (since I often prefer to separate out tricky bits of logic into nearby where clauses without disturbing the main flow of the right-hand side). Moreover, unless I'm missing something, a slight tweak to the desugaring (by adding irrefutable patterns corresponding to the pattern guard bindings) could easily recover the behavior I expected. I'm thinking something like this (which could be tweaked to remove the repeated expression, of course): test2' :: Bar -> Int test2' b | Just v <- toInt b = k where Just v = toInt b k = v + 1 Anyway, what do other people think? Do people besides me find it pleasing to have pattern guard bindings visible in where clauses? Or are people more worried about the failures that would happen if you used a binding from a pattern guard that ended up false? - Ravi