“无全局类型推断”是什么意思?关于Scala 意味着什么?
我读过 Scala 的类型推断不是全局的,因此人们必须在方法上放置类型注释。 (这会是“本地”类型推断吗?)
我只知道一点点,原因是其面向对象的本质,但我不清楚。是否有“全局类型推断”的解释以及为什么 Scala 不能让初学者可以理解?
I have read that Scala's type inference is not global so that is why people must place type annotations on the methods. (Would this be "local" type inference?)
I only a little understand that the reason is from its object-oriented nature, but clarity eludes me. Is there an explanation for "global type inference" and why Scala cannot have it that a beginner might understand?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题是,在具有子类型、重载或类似功能的语言中,HM 类型推断通常是不可判定的。Ref 这意味着可以向推理器添加越来越多的东西,以使其推理出更多特殊情况,但总会有代码会失败。
Scala 决定在方法参数和其他一些地方强制使用类型注释。首先,这似乎很麻烦,但请考虑这有助于记录代码并为编译器提供它可以在一个地方理解的信息。此外,使用 HM 推断的语言经常会遇到这样的问题:有时会在远离原始错误的代码中检测到编程错误,因为 HM 算法只是偶然地(偶然)推断出具有错误类型的代码的其他部分它在失败之前就进行了推断。
Scala 的推理基本上是从外部(方法定义)到内部(方法内的代码)进行的,因此限制了错误类型注释的影响。
具有 HM 推理的语言从内到外工作(忽略添加类型注释的可能性),这意味着单个方法中的微小代码更改有可能改变整个程序的含义。这可能是好是坏。
参考:
子类型类型推断的下限
The problem is that HM type inference is undecidable in general in a language with subtyping, overloading or similar features.Ref This means more and more stuff could be added to the inferencer to make it infer more special cases, but there will always be code where it will fail.
Scala has made the decision to make type annotations in method arguments and some other places mandatory. This might seem like a hassle first, but consider that this helps to document the code and provides the compiler with information it can understand in one place. Additionally, languages with HM inference often suffer from the problem that programming errors are sometimes detected in code far away from the original mistake, because the HM algorithm just went along and happened (by chance) to infer other parts of the code with the faulty type it inferred before it failed.
Scala's inference basically works from the outside (method definition) to the inside (code inside the method) and therefore limits the impact of a wrong type annotation.
Languages with HM inference work from the inside to the outside (ignoring the possibility to add type annotations) which means there is a chance that a small code change in one single method can change the meaning of the whole program. This can be good or bad.
Ref:
Lower bounds on type inference with subtypes
全局类型推断的典型示例是 Hindley-Milner:它需要给定的程序“计算”所有必要的类型。然而,为了实现这一点,给定的语言需要具有一些属性(HM 的扩展试图克服其中一些限制)。 HM 不喜欢的两件事是继承和方法重载。据我了解,这些是 Scala 采用 HM 或其某些变体的主要障碍。请注意,在实践中,即使是严重依赖 HM 的语言也永远无法达到 100% 的推理,例如,即使在 Haskell 中,您有时也需要类型注释。
因此,Scala 使用更有限的(正如你所说的“本地”)形式的类型推断,这仍然比没有好。据我所知,Scala 团队在可能的情况下尝试改进版本之间的类型推断,但到目前为止我只看到了较小的步骤。与 HM 型推理器的差距仍然巨大,并且无法完全缩小。
The typical example for a global type inference is Hindley-Milner: It takes a given program and "calculates" all the necessary types. However in order to achieve this, the given language needs to have some properties (there are extensions to HM, which try to overcome some of these restrictions). Two things HM doesn't like are inheritance and method overloading. As far as I understand these are the main obstacles for Scala to adopt HM or some variant of it. Note that in practice even languages which heavily rely on HM never reach a 100% inference, e.g. even in Haskell you need a type annotation from time to time.
So Scala uses a more limited (as you say "local") form of type inference, which is still better than nothing. As far as I can tell the Scala team tries to improve the type inference from release to release when it is possible, but so far I've seen only smaller steps. The gap to a HM style type inferencer is still huge, and can't be closed completely.