-
Notifications
You must be signed in to change notification settings - Fork 131
Open
@FlorianCassayre
Description
- Scala:
3.X
- scala-parser-combinators:
2.1.1
Consider the following motivating example:
import scala.util.parsing.combinator.Parsers enum Token { case A() case B() case C() } object Parser extends Parsers { override type Elem = Token def tokenA: Parser[Token.A] = ??? def tokenB: Parser[Token.B] = ??? def tokenC: Parser[Token.C] = ??? def tokenABC: Parser[Token.A | Token.B | Token.C] = tokenA | tokenB | tokenC // error }
Unfortunately the definition tokenABC
doesn't compile:
Found: Parser[Token]
Required: Parser[Token.A | Token.B | Token.C]
tokenA | tokenB | tokenC
A workaround is to ascribe tokenA
to the desired union type:
def tokenABC: Parser[Token.A | Token.B | Token.C] = (tokenA: Parser[Token.A | Token.B | Token.C]) | tokenB | tokenC
However this looks unnatural and arguably not very intuitive.
If we look at the source, this is how the choice operator is defined:
def | [U >: T](q: => Parser[U]): Parser[U]
And it is now evident why the code in the above example fails to compile. The obvious change would be to update the signature to:
def | [U](q: => Parser[U]): Parser[T | U]
Which would definitely break cross compatibility and therefore wouldn't be a viable solution.
Metadata
Metadata
Assignees
Labels
No labels