1

I cant get the following code to compile with the latest dotty (0.9.0-RC1), and at first glance it looks like it should...

object UnionMapping {

  private def parse(string: String): Int | Double = {
    if(string.contains("."))
      string.toDouble
    else
      string.toInt
  }

  def test_number = {
    val strings: Seq[String] = Seq("123", "2.0", "42")
    // Works
    val asdf: Seq[AnyVal] = strings.map(parse(_))
    // Fails to compile
    val union: Seq[Int | Double] = strings.map(parse(_))
  }

}

does anyone have any insight into why its failing and whether its expected to work?

stefanobaghino
  • 11,253
  • 4
  • 35
  • 63
aepurniet
  • 1,719
  • 16
  • 24

1 Answers1

2

Currently, type inference almost never infers union types because it usually isn't the best choice. In your particular example I agree that it'd make more sense if it did, so I've opened https://github.com/lampepfl/dotty/issues/4867 to keep track of that. Meanwhile, you can get it to compile by specifying the type arguments by hand:

val union = strings.map[Int | Double, Seq[Int | Double]](parse(_))

Or by hiding the union behind a type alias:

object UnionMapping {

  type Or[A, B] = A | B

  private def parse(string: String): Or[Int, Double] = {
    if(string.contains("."))
      string.toDouble
    else
      string.toInt
  }

  def test_number = {
    val strings: Seq[String] = Seq("123", "2.0", "42")
    val union = strings.map(parse(_))
      // infered type for union is Seq[Or[Int, Double]]
  }

}