向C++程序员解释ML类型推断

Tsu*_*oto 5 c++ templates functional-programming type-inference ml

ML如何在以下函数定义中执行类型推断:

let add a b = a + b
Run Code Online (Sandbox Code Playgroud)

它是否像C++模板一样,在模板实例化之前不执行类型检查,如果类型支持必要的操作,函数可以工作,否则会抛出编译错误?

即,例如,以下功能模板

template <typename NumType>
NumType add(NumType a, NumType b) {
  return a + b;
}
Run Code Online (Sandbox Code Playgroud)

会为...工作

add<int>(23, 11);
Run Code Online (Sandbox Code Playgroud)

但不会起作用

add<ostream>(cout, fout);
Run Code Online (Sandbox Code Playgroud)

我猜的是正确的还是ML类型的推理工作方式不同?

PS:抱歉我的英语不好; 这不是我的母语.

ewe*_*nli 5

我建议你看一下这篇文章:什么是Hindley-Milner?(为什么它很酷)

这是他们用来解释类型推断的最简单的例子(它不是ML,但想法是一样的):

def foo(s: String) = s.length
// note: no explicit types
def bar(x, y) = foo(x) + y
Run Code Online (Sandbox Code Playgroud)

只要查看bar的定义,我们就可以很容易地看到它的类型必须是(String,Int)=> Int.简而言之,这就是类型推断.阅读整篇文章以获取更多信息和示例.

我不是C++专家,但我认为模板是更接近通用性/参数性的其他东西,这是不同的东西.


Jer*_*fin 5

我认为尝试将ML类型推理与C++中的几乎任何事物联系起来更容易导致混淆而不是理解.C++根本没有任何类似于类型推断的东西.

C++中唯一没有明确键入的部分是模板,但(大多数情况下)它们支持泛型编程.像你给出的C++函数模板可能同样适用于一组无限类型 - 例如,你NumType用作模板参数的代码,但是可以使用字符串.一个程序可以实例化你add在一个地方添加两个字符串,在另一个地方添加两个数字.

ML类型推断不适用于通用编程.在C或C++中,您显式定义了参数的类型,然后编译器会检查该类型是否允许您尝试对该参数执行的所有操作.ML扭转这一:它看着你与参数做的事情,并计算出什么类型具有成为你能够做这些事情.如果你试图做一些相互矛盾的事情,它会告诉你没有能够满足约束条件的类型.

这在C或C++中几乎是不可能的,主要是因为允许的所有隐式类型转换.例如,如果我有类似于a + bML的东西,它可以立即得出结论a并且b必须是整数 - 但在C或C++中,它们几乎可以是整数或指针或浮点类型的任意组合(具有它们可以的约束) "T 二者是指针)或使用定义的类型的过载operator+(例如,std::string).在ML中,在最坏的情况下找到类型可以是指数,但几乎总是非常快.在C++中,我估计它更频繁地呈现指数,并且在很多情况下可能会受到约束,因此给定的函数可能具有许多不同的签名.

  • 使用`auto`关键字,C++ 0x具有本地类型推断(如C#,但更为通用).但这当然与欣德利 - 米尔纳相去甚远.基本上,它仅在声明点起作用,并且只有在使用常量表达式立即初始化变量时才起作用. (2认同)