~ patterns

John Meacham john at repetae.net
Mon Jan 30 21:35:06 EST 2006

I also use ~ patterns quite regularly and would be quite put off by
their removal. and I know just how hard they are to implement :) I do
look forward to using ! patterns too. I often find that making things
more strict can often make things worse space-wise if not done quite
carefully and the same is true of making things too lazy. being able to
finely control this in both directions is a very useful feature.

in any case, I thought I'd mention my favorite use of ~ patterns which
is not actually their intended use.

I use them to enforce preconditions that I don't expect a pattern match
to fail. this is mainly used in list comprehensions.

if I have a type like

data E = EVar Var | EAp E E

say I want to change the type on a list of variables, a list
comprehension is often the nicest way to do it (imagine this were more
complicated such that a list comprehension actually is needed)

[ setType t v | EVar v <- vs | t <- ts ]

now, I expect vs to be all variables, but imagine a bug makes an EAp
float in there, suddenly my list is truncated mysteriously and odd
things happen because the types all get offset by one!

so I write it like this

[ setType t v | ~(EVar v) <- vs | t <- ts ]

it both documents my intent, and causes the compiler to enforce it at
run time.

another use I would use more if ghc got its incomplete pattern matching
warning algorithm correct would be to document when I intend a pattern
match to be partial

f (Foo a) = a
f ~(Bar x) = x

this means that I expect the argument to never be anything other than a
Foo or Bar so it is okay that I don't have more cases. again, it is both
for documentation of intent and to suppress the compiler warning.


John Meacham - ⑆repetae.net⑆john⑈ 

More information about the Haskell-prime mailing list