【问题标题】:Explain ML type inference to a C++ programmer向 C++ 程序员解释 ML 类型推断
【发布时间】:2011-02-10 07:15:57
【问题描述】:

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

let add a b = a + b

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

即比如下面的函数模板

template <typename NumType>
NumType add(NumType a, NumType b) {
  return a + b;
}

适用于

add<int>(23, 11);

但不适用于

add<ostream>(cout, fout);

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

PS:对不起我的英语不好;这不是我的母语。

【问题讨论】:

  • 你问的是类型推断还是类型检查?
  • 推理。在我的示例中,从 ML 函数定义中推断出哪些类型?

标签: c++ functional-programming templates type-inference ml


【解决方案1】:

ML 使用Hindley-Milner type inference。在这个简单的例子中,它所要做的就是查看函数的主体,看看它使用+ 和参数并返回它。因此它可以推断出参数必须是+ 接受的参数类型(即ints),并且函数返回+ 返回的类型(也是int)。因此add 的推断类型为int -&gt; int -&gt; int

注意在SML(但不是CAML)中+也定义了除int以外的其他类型,但是当有多种可能性时它仍然会推断int(即你定义的add函数不能用于添加两个花车)。

【讨论】:

    【解决方案2】:

    我建议你看看这篇文章:What is Hindley-Milner? (and why is it cool)

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

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

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

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

    【讨论】:

    • 我不明白的是,为什么 fun func(a, b) = a + b 中的 ab 的类型不能推断为 real (浮点)。那是因为int 的优先级高于real
    • 可能是因为s.length 返回int,我错了吗?
    【解决方案3】:

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

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

    ML 类型推断不适用于泛型编程。在 C 或 C++ 中,您显式定义参数的类型,然后编译器检查您尝试对该参数执行的所有操作是否为该类型所允许。 ML 反过来:它查看您对参数所做的事情,并确定您能够执行这些操作的类型 是什么。如果您尝试做相互矛盾的事情,它会告诉您没有可以满足约束的类型。

    这在 C 或 C++ 中几乎是不可能的,主要是因为所有允许的隐式类型转换。例如,如果我在 ML 中有类似 a + b 的东西,它可以立即得出结论,ab 必须是整数——但在 C 或 C++ 中,它们几乎可以是整数、指针或浮点数的任意组合点类型(限制它们不能都是指针)或使用重载operator+ 的已定义类型(例如std::string)。在 ML 中,在最坏的情况下查找类型可能是指数级的,但几乎总是非常快。在 C++ 中,我估计它更频繁地呈指数增长,并且在很多情况下可能会受到不足的约束,因此给定的函数可以具有多种不同签名中的任何一种。

    【讨论】:

    • C++0x 具有使用 auto 关键字的局部类型推断(类似于 C#,但更通用)。但这当然与 Hindley-Milner 相去甚远。基本上,它只在声明时有效,并且只有在变量立即用常量表达式初始化时才有效。
    【解决方案4】:

    F# 和 ML 在类型推断方面有些相似,所以您可能会发现

    Overview of type inference in F#

    有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-25
      • 2010-10-01
      • 2012-10-16
      • 1970-01-01
      • 2016-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多