Pattern guards and where clauses

Lemmih lemmih at gmail.com
Sun Nov 19 21:23:12 EST 2006


On 11/20/06, Ravi Nanavati <ravi at bluespec.com> wrote:
> 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?

What about this case:

> test2 :: Bar -> Int
> test2 b | Just v <- toInt b = k
>        | v <- () = k
>        | otherwise = k
>    where k = v + 1
> test2 _ = 0

Making bindings available outside their scope is just plain wrong (and
obviously so), imo. Perhaps you're looking for a let-expression
instead of a where-clause?

-- 
Cheers,
  Lemmih


More information about the Haskell-prime mailing list