Skip to content

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

New issue

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

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

Already on GitHub? # to your account

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.

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

No branches or pull requests

1 participant