【问题标题】:How does Dotty decide how to infer/when to widen Union Types?Dotty 如何决定如何推断/何时扩大联合类型?
【发布时间】:2021-01-03 16:29:28
【问题描述】:

已经讨论了扩大联合类型here,但我似乎无法找到以下案例的答案

让我们从以下内容开始

val x = List(1, 2, "a")

这个异构列表被推断为List[Any],就像在 Scala 2 中一样

然而以下

val x2 = List(List(1, 2), Vector("a", "b"))

推断为List[scala.collection.immutable.AbstractSeq[Int | String]]

这是相当令人困惑的行为。为什么两种不相交类型的 LUB 在一种情况下被推断为 Any 而在另一种情况下被推断为联合类型?

如果这只是一个设计决策,是否有任何需要注意的情况?

【问题讨论】:

    标签: scala type-inference union-types dotty scala-3


    【解决方案1】:

    smarter 状态

    我们避免推断联合类型的原因与我们避免推断的原因相同 单例类型,因为有时它们“过于精确”

    我对这句话的解释是,将List(1,2) 输入为List[Int] 而不是List[1 | 2],或者将List(new Cat, new Dog) 输入为List[Animal] 而不是List[Cat | Dog] 更有意义。

    另见 Dmytro 来自相关question(我的)的评论

    引用guillaume.martres.me/talks/dotty-tutorial/#/1/13(幻灯片 15 "类型推断和联合类型"): "默认情况下,Dotty 不推断 联合类型,它们由非联合超类型近似。联盟 类型可能“过于精确”并阻止合法代码编译”

    另请参阅23:38 中提到的“Dotty 和类型:迄今为止的故事”。

    但是根据smarter,只执行一次联合扩展以避免无限LUB:

    当我们进行一次扩展时,结果类型可能有一个联合 某处(如Join of a union type 部分中的示例 doc),如果我们确实递归地进行扩展,我们将不会扩展它, 我们确实可以得到一个无限的 lub

    【讨论】:

    • 我看到了那条评论和视频,但老实说,它并没有完全回答我的问题。我想我对他们为什么决定不推断联合类型有一些了解,但我仍然不清楚为什么在你的例子中,List[Box[Square | Circle]] 被推断为联合?如果推断联合类型很难,为什么在这种情况下不难?我错过了 cmets 或视频中的某些内容吗?
    • @sinanspd 根据smarter,似乎只执行一次联合扩展以避免无限 lub:“如果我们确实递归地进行扩展,我们确实可以获得无限 lub” 另见Join of a union type
    • 感谢马里奥!我认为交叉点类型阻止了无限 lub,但我想这个故事还有更多。您能否在答案中发表纪尧姆的评论,以便我接受?我认为这是对这个问题最直接的答案
    猜你喜欢
    • 2020-09-30
    • 2023-02-11
    • 2020-12-15
    • 2011-11-15
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 2022-01-05
    • 2018-07-26
    相关资源
    最近更新 更多