You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala3中函数可接受超类型?List.fill类型标注存疑

Scala3中List.fill部分应用的类型疑问解答

代码与现象

示例代码:

val times4 = List.fill(4)
val oranges = times4("orange")
println(oranges)

运行输出:

List(orange, orange, orange, orange)

IntelliJ显示times4的类型为:

Nothing => List[Nothing]

问题解答

  1. 行为是否正确?
    完全正确。这是Scala3类型推导、泛型协变与类型参数特化共同作用的结果。

List.fill(n)的签名是def fill[A](n: Int)(elem: A): List[A],当仅传入第一个参数4时,得到的是一个部分应用函数。此时Scala3会先将泛型参数A临时推断为Nothing(Scala类型系统的底部类型),但这只是编辑器未看到后续调用时的中间推断结果。

当调用times4("orange")时,Scala会对这个部分应用函数进行类型特化,将泛型参数A重新推断为String。由于Nothing是所有类型的子类型,结合函数类型的协变/逆变特性,Nothing => List[Nothing]会被自动适配为String => List[String],因此可以正常接收String参数。

  1. 函数是否可接受超类型?
    这里的本质并非函数直接接受超类型,而是Scala的类型系统会在函数调用时重新解析泛型参数,修正初始的类型推断结果。

List.fill(4)返回的实际是一个泛型函数,可理解为[A] => A => List[A](Scala3的上下文泛型推导会自动处理这种延迟的类型绑定)。编辑器显示的Nothing => List[Nothing]只是未看到后续调用时的临时类型,当传入String参数后,泛型参数A被确定为String,函数实际类型就变为String => List[String],自然可以接收String参数。

总结:该行为是Scala3泛型系统的正常表现,编辑器的类型显示为中间状态,实际运行时的类型推断会根据调用场景完成正确绑定。

内容的提问来源于stack exchange,提问作者Mandroid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 19:50:48