- 
                Notifications
    You must be signed in to change notification settings 
- Fork 131
Open
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 | tokenCHowever 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.
zoerb and bodograumann
Metadata
Metadata
Assignees
Labels
No labels