question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Type parameter inference is too eager to widen union types

See original GitHub issue

From https://stackoverflow.com/questions/51575183/dotty-seq-mapping-to-union:

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(_))
  }
}

There’s enough hints here that type inference should be able to do the right thing and not widen Int | Double to AnyVal.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
smartercommented, Jul 31, 2018

The current logic is here: https://github.com/lampepfl/dotty/blob/34baac4b69ef9bc764c8a6d0d4c8cd458759a5e4/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala#L297-L301

To give some context: we avoid inferring union types for the same reason we avoid inferring singleton types, because sometimes they’re “too precise”. E.g.:

scala> List(1, "")
val res0: List[Any] = List(1, )

scala> List(if (true) 1 else "")
val res1: List[Any] = List(1)

The problem is that we do not distinguish between an inferred union type and a union type actually written down by the user:

scala> val x: Int | String = 1
val x: Int | String = 1

scala> List(x)                                                                                                                                                                                                                               
val res2: List[Any] = List(1)

This is tricky to fix since we’d need to have a way to distinguish | written down by the user from | made up by the compiler (maybe using an annotation?).

(If you’re looking for issues related to type inference, I’ve left a sketch of how to fix things in https://github.com/lampepfl/dotty/issues/4742, but it’s not super easy either)

0reactions
oderskycommented, Mar 8, 2020

This works by now.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why no type inference for union types? - Scala Contributors
Union types are excellent feature addition to scala. But I feel very limited as it does not provide type inference like other types....
Read more >
How Does Dotty Decide How To Infer/When To Widen Union ...
Union types are useful for modeling situations when values can overlap in the types ... Type parameter inference is too eager to widen...
Read more >
Why isn't the type argument inferred as a union type?
TypeScript in general will not synthesize a union type during generic inference. The reason, in simplified terms, is that it's not desirable ...
Read more >
Denotable union and intersection types : KT-13108 - YouTrack
By "denotable" we mean, that it will be possible to explicitly specify union and intersection types property types, as parameter types, are return...
Read more >
Chapter 18. Type Inference
Note that if the target type is an inference variable, or if the target type's parameter types contain inference variables, we produce false....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found