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
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