Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scala 3 union types don't always play nicely with choice #455

Open
FlorianCassayre opened this issue Apr 6, 2022 · 0 comments
Open

Scala 3 union types don't always play nicely with choice #455

FlorianCassayre opened this issue Apr 6, 2022 · 0 comments

Comments

@FlorianCassayre
Copy link

FlorianCassayre commented Apr 6, 2022

  • 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant