in earlier examples, we have seen how a monadic data parsing framework
allows us to move from built-in case constructs to composable match alternatives,
where the alternatives are represented by lambda-matches; we have then seen
how this enables us, eg., to combine data parsing and string parsing to specify
parsers and unparsers by the same combinator grammar.
this, probably the final example in this series, is rather more speculative,
showing a sketch of moving beyond composable match alternatives, to
composable patterns (aka pattern abstractions, views, first-class patterns, ..).
we can use the same monadic data parsing framework, but if we want to
avoid further syntactic sugar, we either have to abandon pattern variables,
or we have to play some tricks. the attached files outline
- a sketch of a simple pattern library supporting pattern variables,
as-patterns, wildcards and composable match rules (single argument
match rules only here)
- as an example of using this pattern library, a user-defined array-based
list type, with user-defined pattern constructors (cons and snoc views)
[the type is not all that interesting in itself, I just needed an example
that didn't already come with algebraic data constructors/patterns]
it is also vaguely related to ByteString, so you could define pattern
constructors for that as well (*after* expanding this sketch of a
pattern library into a somewhat safer version, of course!-)
using the pattern library, match rules generally look like this:
(lhs ==> rhs)
and are composed using the usual lambda-match combinators
splice $ (lhs1 ==> rhs1) +++ ... +++ (lhsN ==> rhsN)
if a match rule involves pattern variables, it'll look like this:
(vV $ \v1..vn-> Vv $ lhs ==> rhs)
where a pattern variable v may be bound in lhs using (v|!), and refered
to in rhs using (v|?). this pattern-variable workaround avoids syntactic
sugar ("look, ma! first-class patterns with variables, without sugar!":-),
but makes match rules look more clumsy (also, no attempt has been
made (yet) to safeguard these variable accesses).
since we define all our own patterns here, this example doesn't need
the syntax patch for lambda-match, only the lambda-match libraries
(I've tested it in Hugs) - in fact, the main purpose of that syntax patch
is to incorporate all the work invested in conventional matches into
the monadic data parsing framework (have I now mentioned this
terminology often enough?-).
enjoy (and let me know if I have convinced any more of you!-)
Claus
ps GHC HQ have agreed to incorporate the lambda-match syntax patch,
once I extend it with documentation and test cases; so that is good news;
I guess the next step after that will be to pitch the support library to
the libraries list, and perhaps to get Hugs and others to follow suit wrt
the syntax patch.
to avoid confusion: nothing in this example email is part of my Haskell'
proposal, it is just a motivating example showing what could be built
on top of lambda-match in the future. I do hope it'll help to convince
people that lambda-match itself is not just a trivial clean-up of the
language report or an odd way to write patterns, but an interesting
lever and point of entry into the exciting world of composable matches
and monadic data parsing (there, I said it again!-).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ControlMonadPattern.hs
Type: application/octet-stream
Size: 1668 bytes
Desc: not available
Url : http://www.haskell.org/pipermail/haskell-prime/attachments/20061121/a18dad2a/ControlMonadPattern.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: LambdaMatchPatterns.hs
Type: application/octet-stream
Size: 2782 bytes
Desc: not available
Url : http://www.haskell.org/pipermail/haskell-prime/attachments/20061121/a18dad2a/LambdaMatchPatterns.obj