parboiled2
parboiled2 copied to clipboard
Support zeroOrMore for Rule2+
The following code
def f: RuleN[Int :: Int :: Int :: HNil] = ???
def g = rule { zeroOrMore(f) }
results in the following error:
- The optional, zeroOrMore, oneOrMore and times modifiers can only be used on rules of type
Rule0, Rule1[T] and Rule[I, O <: I]!
This restriction is tedious, why does it exist? I worked around the problem by nesting the return value:
def f: RuleN[(Int :: Int :: Int :: HNil) :: HNil] = ???
But this requires further overhead by constructing the return value and by destructing it afterwards. Are there other workarounds?
Currently the typing is like this (one of the three possible cases):
zeroOrMore(RuleN[A :: HNil]): RuleN[Seq[A] :: HNil]
or shorter
zeroOrMore(Rule1[A]): Rule1[Seq[A]]
What would you like the type of
zeroOrMore(RuleN[A :: B :: C :: HNil])
to be?
Looking in more detail to the types, I can see why it does not work but it is still a very weird limitation and one that makes handling rules that produce multiple values a lot harder.
What you want is this:
zeroOrMore(RuleN[T :: HNil]): RuleN[Seq[T] :: HNil]
zeroOrMore(RuleN[T :: T :: HNil]): RuleN[Seq[T] :: HNil]
zeroOrMore(RuleN[T :: T :: T :: HNil]): RuleN[Seq[T] :: HNil]
...
which I think is actually a reasonable request. I'm going to reopen the ticket.
Actually, what I want is
zeroOrMore(RuleN[A :: B :: C :: ... :: HNil]): RuleN[Seq[A :: B :: C :: ... :: HNil] :: HNil]
i.e. return multiple values (of different type) every time the rule is called.
If that's what you want you can simply group your values into a tuple, no?
Yes indeed I can do that. Another thing I overlooked.