Pattern guards and where clauses
Simon PeytonJones
simonpj at microsoft.com
Mon Nov 20 04:14:07 EST 2006
 From an implementation perspective, I understand the behavior as an
 artifact of desugaring pattern guards into a case expression. But, as a
It's definitely not an artefact of the implementation; it's just a consequence of Haskell's design.
'where' clauses scope over multiple guards, and must do so
f x  wibble > 0 = rhs1
 wibble < 0 = rhs2
 otherwise = rhs3
where
wibble = sqrt x + 77
Remember you can use 'let' in pattern guards
test2 :: Bar > Int
test2 b  Just v < toInt b,
let k = v+1
= k
Simon
 Original Message
 From: haskellprimebounces at haskell.org [mailto:haskellprimebounces at haskell.org] On Behalf Of
 Ravi Nanavati
 Sent: 20 November 2006 01:47
 To: haskellprime at haskell.org
 Subject: Pattern guards and where clauses

 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 righthand 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
 _______________________________________________
 Haskellprime mailing list
 Haskellprime at haskell.org
 http://www.haskell.org/mailman/listinfo/haskellprime
More information about the Haskellprime
mailing list