Types 什么是完全类型推断语言?这种语言的局限性是什么?

Types 什么是完全类型推断语言?这种语言的局限性是什么?,types,programming-languages,functional-programming,type-inference,type-systems,Types,Programming Languages,Functional Programming,Type Inference,Type Systems,据我所知,任何编程语言在编写函数或模块时不需要在源代码中编写类型注释,如果代码块是“类型正确的”,编译器将推断类型并编译代码。还有别的吗 有这样的语言吗?如果是,其类型系统是否有任何限制 更新1: 只是想说清楚,我想问的是一种静态类型的、全类型推断的编程语言,而不是一种动态类型的编程语言。全类型推断的局限性在于它不能与许多高级类型系统功能一起工作。作为一个例子,考虑Haskell和OcAML。这两种语言几乎都是完全类型推断的,但都有一些可能干扰类型推断的特性 在Haskell中,它的类型类与多

据我所知,任何编程语言在编写函数或模块时不需要在源代码中编写类型注释,如果代码块是“类型正确的”,编译器将推断类型并编译代码。还有别的吗

有这样的语言吗?如果是,其类型系统是否有任何限制

更新1:
只是想说清楚,我想问的是一种静态类型的、全类型推断的编程语言,而不是一种动态类型的编程语言。

全类型推断的局限性在于它不能与许多高级类型系统功能一起工作。作为一个例子,考虑Haskell和OcAML。这两种语言几乎都是完全类型推断的,但都有一些可能干扰类型推断的特性


在Haskell中,它的类型类与多态返回类型相结合:

readAndPrint str = print (read "asd")
这里的
read
是一个类型为
reada=>String->a
的函数,这意味着“对于支持类型类
read
的任何类型
a
,函数
read
可以接受
String
并返回
a
。因此如果
f
是一个接受int的方法,我可以写
f(读“123”)
它会将“123”转换为Int 123并调用
f
。它知道应该将字符串转换为Int,因为
f
接受Int。如果f接受Int列表,它会尝试将字符串转换为Int列表。没问题

但是对于上面的
readAndPrint
函数,这种方法不起作用。这里的问题是
print
可以接受任何可以打印的类型的参数(即支持
Show
typeclass的任何类型)。因此,编译器无法知道是否要将字符串转换为int、int列表或任何其他可以打印的内容。因此,在这种情况下,需要添加类型批注


在OCaml中,有问题的功能是类中的多态函数:如果定义一个函数,该函数以对象为参数并调用该对象上的方法,编译器将推断该方法的单态类型。例如:

let f obj = obj#meth 23 + obj#meth 42
foo = let bar (f :: forall a.[a]->[a]) = (f ['a', 'b', 'c'], f [1,2,3]) in bar reverse
在这里,编译器将推断出
obj
必须是一个类的实例,该类具有一个名为
meth
int->int
类型的方法,即一个接受int并返回int的方法。您现在可以定义一组具有此类方法的类,并将该类的实例作为参数传递给
f
。没问题

如果使用类型为
'a.'a->int
的方法定义类,即可以接受任何类型的参数并返回int的方法,则会出现问题。不能将该类的对象作为参数传递给
f
,因为它与推断的类型不匹配。如果希望
f
将此类对象作为其参数,唯一的方法是向
f
添加类型注释


因此,这些都是几乎完全类型推断的语言的例子,以及它们不完全类型推断的例子。如果你从这些语言中删除有问题的特性,它们将是完全类型推断的


因此,没有这些高级功能的ML的基本方言是完全类型推断的。例如,我假设Caml Light是完全类型推断的,因为它基本上是没有类的OCaml(但是我实际上不知道语言,所以这只是一个假设)。

什么是类型推断?

从历史上看,类型推断(或类型重构)意味着程序中的所有类型都可以派生出来,而不需要任何显式的类型注释。然而,近年来,在主流编程语言中,将自下而上类型推断的最简单形式都称为“类型推断”已成为一种时尚(例如,新的C++11的
auto
declarations)。因此,人们开始添加“full”来表示“真实”的东西

什么是完整类型推理?

一种语言在多大程度上可以推断类型,在实践中,几乎没有一种语言支持最严格意义上的“完整”类型推断(核心ML是唯一的例子)。但主要区别因素是是否可以为没有“定义”的绑定派生类型“附加到它们-特别是函数的参数。如果你能写

f(x) = x + 1
类型系统计算出f.g.有Int类型→ Int,那么称这种类型推断是有意义的。此外,我们讨论多态类型推断,例如

g(x) = x
已指定泛型类型∀(t) t→ 我不会自动地

类型推理是在简单类型lambda演算的背景下发明的,多态类型推理(又名Hindley/Milner类型推理,发明于20世纪70年代)是ML语言家族(标准ML、OCaml和Haskell)的成名之作

完整类型推断的限制是什么?

Core ML拥有“完整”多态类型推断的优势。但它依赖于其类型系统中多态性的某些限制。特别是,只有定义可以是泛型的,而不是函数参数。也就是说

id(x) = x;
id(5);
id(True)
工作正常,因为当定义已知时,
id
可以被赋予多态类型

f(id) = (id(5); id(True))
不在ML中进行类型检查,因为
id
不能作为函数参数是多态的∀(t) t→ t、 但不是所谓的高阶多态类型,比如(∀(t) t→ (t)→ Bool,其中多态值是以一流的方式使用的(这一点很清楚,即使是极少数显式类型语言也允许)

多态lambda演算(也称为“系统F”)是显式类型的,允许后者
foo = let bar (f :: forall a.[a]->[a]) = (f ['a', 'b', 'c'], f [1,2,3]) in bar reverse