[Haskell-cafe] Fixity parsing, Template Haskell

Reiner Pope reiner.pope at gmail.com
Fri Nov 21 07:59:48 EST 2008


This post follows on from a discussion about a month ago, called
"Haskell Syntax Inside Quasiquote".

To summarise,  suppose I want to create a Haskell quasiquoter for lists, eg
  [$list|1,x^2,y,3|]      (representing the list [1,x^2,y,3])
Ideally, this would allow arbitrary Haskell expressions for each
element of the list (provided, of course, that the types are correct).

To write this list quasiquoter, I would need to parse Haskell
expressions. This is doable[1], but is necessarily buggy when infix
operators are concerned. For instance, a user of the list quasiquoter
may define two new operators, (+*) and (+^), and then write
  [$list|1+*2+^3|]
Being able to correctly parse such an expression depends on known the
two operator's fixities, which is currently impossible. The problem is
that potentially non-local fixity declarations affect parsing.

As far as I can see, the correct solution is to change the Template
Haskell AST representation of fixity expressions from
> data Exp = ...
>   | InfixE (Maybe Exp) Exp (Maybe Exp)
to something like
> type Op = Exp --- because TH doesn't distinguish operators from expressions
> data Exp = ...
>  | InfixE [Exp] [Op]  --- length [Exp] == 1 + length [Op], always
>  | LeftSection Exp Op
>  | RightSection Op Exp
Apart from splitting of the sections, the important difference is that
the expressions are parsed as a list of expressions separated by
operators. So, my example above would be parsed as something like

InfixE [parseExp "1", parseExp "2", parseExp "3"] ["+*", "+^"]

Then, when Template Haskell performs the splice, it could correctly
resolve the fixities.

Of course, this would require a change to Template Haskell, so a
second-best solution would be to forbid unparenthesised expressions in
my quasiquoter. Then, parsing can proceed correctly without knowing
the fixities. This would be easiest to do if haskell-src-exts changed
its AST in a similar way to described above for Template Haskell.

Any thoughts?

Cheers,
Reiner Pope

[1] For instance, see haskell-src-meta, which uses haskell-src-exts as
a parser, and then converts the AST into a form that Template Haskell
recognises.


More information about the Haskell-Cafe mailing list