[Template-haskell] Custom patternmatching for ADTs and Emulating TH
Pattern splicing (was quasiquoting and guards)
Alfonso Acosta
alfonso.acosta at gmail.com
Thu Jun 26 15:35:41 EDT 2008
On Wed, Jun 25, 2008 at 11:19 PM, Reid Barton <rwbarton at math.harvard.edu> wrote:
> Hi all,
>
> I'd like to use quasiquotation to emulate bash's case statement in
> Haskell.
Nice Idea. I've been thinking about using quasiquoting patters for
regular expression matching for a while. Never found the time to code
it though.
> I tried (ab)using view patterns, but
> they're not yet supported by Template Haskell.
Right, I think that would be the nicest approach (if they were
supported of course and I would really like to see this implemented).
Then, your initial expression ...
example x = case x of
[$rx|.*foo.*] -> "contains foo"
_ -> "doesn't contain foo"
Could be expanded to
example x = case x of
(match ".*foo.*" -> True) -> "contains foo"
_ -> "doesn't contain foo"
Sadly, I cannot think about any solution working with current version
of GHC. I considered patternguards, but after all, they have the same
problem you mentioned for standard ones ...
--
Now, some unrequested comments about view patterns+quasiquotes:
Pattern quasiquotes and patternviews match nicely, allowing to
patternmatch ADT's using custom syntax.
For example, imagine a vector ADT. It's closest view (against which
standard patter matching is possible) would probably be a list.
However, it would be more appropriate to be able to match using custom
syntax other list patterns, say <1,2,3>, to patternmatch a vector with
three specific elements. With quasiquoters and views one could do
f :: VectorADT Int -> Result
-- v is the quasiquoter for vectors
f [$v|<1,2,3>] = ...
which IMHO is much nicer than
f :: VectorADT Int -> Result
f (toList -> [1,2,3]) = ...
In order to implement this, it would be required to
* have view pattern support in TH.
* have a Haskell pattern parser returning TH's AST (parseHaskellPat ::
String -> Pat) (which as far as known no one has implemented yet).
This parser could also serve to build a quasiquoter with which to
emulate splicing patterns with Template Haskell, that is [p| |], which
isn't currently implemented (see
http://hackage.haskell.org/trac/ghc/ticket/1476).
So, I think I'll get my hands dirty on it. My best bet is probably
using Language.Haskell.Parser and then implement a translator from
Language.Haskell.Syntax to Language.Haskell.TH.Syntax .
Another option would be using GHC's Haskell parser and its translator
from GHC's AST to Language.Haskell.TH.Syntax (basically steal the
implementation of [| |]). However, since my knowledge of GHC's
internals is almost null, I'm not sure if I should do that, whether
it's even possible or if it would worth the effort. The GHC gurus can
probably clarify this.
What do think? I would certainly appreciate some feedback and
suggestions before I start to code.
More information about the template-haskell
mailing list