【发布时间】:2010-11-29 13:04:54
【问题描述】:
我读到 Scala 的类型推断不是全局的,所以人们必须在方法上放置类型注释。 (这会是“本地”类型推断吗?)
我只知道一点点,原因在于它的面向对象的性质,但我无法理解。是否有关于“全局类型推断”的解释以及为什么 Scala 不能让初学者理解?
【问题讨论】:
标签: scala type-inference static-typing
我读到 Scala 的类型推断不是全局的,所以人们必须在方法上放置类型注释。 (这会是“本地”类型推断吗?)
我只知道一点点,原因在于它的面向对象的性质,但我无法理解。是否有关于“全局类型推断”的解释以及为什么 Scala 不能让初学者理解?
【问题讨论】:
标签: scala type-inference static-typing
问题在于,在具有子类型化、重载或类似特性的语言中,HM 类型推断通常是不可判定的。Ref这意味着可以将越来越多的东西添加到推断器中以使其推断出更多特殊情况,但是总是会失败的代码。
Scala 已经决定在方法参数和其他一些地方强制使用类型注释。首先这可能看起来很麻烦,但考虑到这有助于记录代码并为编译器提供它可以在一个地方理解的信息。此外,具有 HM 推理的语言经常会遇到这样的问题,即有时在远离原始错误的代码中检测到编程错误,因为 HM 算法只是继续并发生(偶然)以错误类型推断代码的其他部分它在失败之前推断出来。
Scala 的推理基本上是从外部(方法定义)到内部(方法内的代码)起作用,因此限制了错误类型注释的影响。
具有 HM 推理的语言从内到外工作(忽略添加类型注释的可能性),这意味着单个方法中的小代码更改可能会改变整个程序的含义。这可能是好是坏。
【讨论】:
全局类型推断的典型示例是Hindley-Milner:它采用给定程序并“计算”所有必要的类型。然而,为了实现这一点,给定的语言需要具有一些属性(HM 有一些扩展,它们试图克服其中的一些限制)。 HM 不喜欢的两件事是继承和方法重载。据我了解,这些是 Scala 采用 HM 或它的某些变体的主要障碍。请注意,在实践中,即使是严重依赖 HM 的语言也永远无法达到 100% 的推理,例如即使在 Haskell 中,您有时也需要类型注释。
所以 Scala 使用了更有限的(如您所说的“本地”)类型推断形式,总比没有好。据我所知,Scala 团队试图在可能的情况下改进从发布到发布的类型推断,但到目前为止,我只看到了更小的步骤。与 HM 风格类型推理器的差距仍然很大,无法完全缩小。
【讨论】: