invertible-syntax
invertible-syntax copied to clipboard
example of composing parsers with Coproduct
Num literals, Add, and Mul nodes each implemented as separate parsers, injecting their results into an arbitrary type.
Successive example parsers constructed by adding more types to a Coproduct, and finally a proper recursive parser using parens.
Now using Matryoshka just for Fix
.
Had some time before getting back on the road and couldn't resist giving this a try. It certainly works, and without any changes to the actual Iso/Syntax library. On the other hand, it's fairly cumbersome and inference seems to go off the rails in a couple of places. Surprise, surprise.
Furthermore, the added complexity seems to call for a re-thinking of some of the types and their names. Namely, Syntax
, Parser
, and Printer
all seem to be misleading. A better scheme might be something like:
- what's currently
Syntax
will becomeSyntaxHandler
. This type will only ever be implemented twice, by the library, asParserSyntaxHandler
andPrinterSyntaxHandler
, unless someone thinks of a new way to use these declarations (like generating parse-tree visualizations or something.) - what's currently
Parser
becomestype ParserF[A] = Source => ...
. This is the strange internal type which handles partial parsing, which users never see. -
type Syntax[P[_], T[_]] = SyntaxHandler[P] => P[T]
. This ends up being the type of the function you actually need to write, and it's always been confusing that it wasn't actually calledSyntax
. -
type Parser[A] = String => (ParseFailure \/ A)
. This will be the type you actually get to use for parsing, and now it would be calledParser
, which makes sense. -
type Printer[A] = A => Option[Cord]
remains the same, because it happens to work for both since printing is always unambiguous. I suppose we could dotype PrinterF[A] = A => Option[Cord]
andtype Printer[A] = A => Option[String]
, just because dealing withCord
is annoying. I know you'd like to seeOption
go away, but I think it's inherent in the fact that some values might not be representable inString
form (for example, my new syntax that says vars are arbitrarySymbol
s but happens to only parse and print single-char names.)
I will probably give that reworking a try, because I think it will help quite a bit. Unfortunately it will take this library even further away from the original paper.
This looks pretty cool. I just glanced at it, but I’ll take a deeper look tomorrow or Monday.
@sellout: just getting around to pushing some minor changes I did the other day.
I think this is promising and probably worth merging but before I would call the experiment a success I would want to implement a properly complex grammar, with a dozen or more operators and precedence levels. But I hesitate to try it because inference is already not really working when I add just the third type to the coproduct. Not sure how to proceed.
Try adding the SI-2712 plugin. Just a good idea in general, maybe it'll help the inference here.