除模板函数之外的OCaml多态性示例?

Suz*_*ioc 3 c++ oop generics polymorphism ocaml

我试图了解自己,OCaml语言有多种形式的多态性.

我是一个例子

let id x = x
Run Code Online (Sandbox Code Playgroud)

这个例子不等同于C++模板函数

template<class A> A id(A x) { return x; }
Run Code Online (Sandbox Code Playgroud)

如果是这样,那么我的问题是:OCaml中是否还有其他形式的多态性?这个概念在命令式语言的世界中被称为"通用算法",而不是"多态".

sep*_*p2k 13

基本上有三种语言功能,有时称为多态性:

  • 参数多态(即"泛型")
  • 子类型多态性,这是一种类型的子类型提供比超类型更具体的操作版本的能力,即覆盖方法的能力(以及运行时系统调用基于方法的正确实现的能力)关于对象的运行时类型).在OO语言中,这通常简称为"多态".
  • 所谓的ad-hoc多态,即重载函数/方法的能力.

正如您已经发现的那样,OCaml具有参数多态性.它还具有亚型多态性.它没有ad-hoc多态性.

因为在你的标题中你已经要求举例,这里是OCaml中子类型多态的一个例子:

class c = object
    method m x = x+1
end

class d = object
    inherit c
    method m x = x+2
end

let main = 
    let o:c = new d in
    print_int (o#m 2)
Run Code Online (Sandbox Code Playgroud)

这将打印4.


Jac*_*ack 5

这种多态性称为泛型编程,但其背后的理论概念称为参数多态性

您提供的两个示例确实显示了参数多态性,但 OCaml 由强大的推断类型检查器支持,而不是 C++ 提供的检查器(这是一种更实用且有更多警告的解决方案),因此真正的区别在于,在 C++ 中,代码是重复的对于在 OCaml 中在代码中使用的每种类型,类型检查器都会通过验证是否存在通过统一来替换隐式类型变量来解析它。

OCaml 中的所有内容都可以是多态的,因为通常没有任何内容用类型进行注释,因此在实践中,如果某些内容可以用作任何函数的参数,那么它是隐式允许的。

例如,您可以使用类型变量来定义多态方法:

let swap ((x : 'a), (y : 'b)) : 'b * 'a = (y, x)
Run Code Online (Sandbox Code Playgroud)

这样无论'ao'b是什么类型,它都可以工作。

OCaml 的另一个强大的多态功能是函子(不是常见的 C++ 函子),而是由其他模块参数化的模块。这个概念听起来更可怕,但它们确实代表了 OCaml 代码的更高阶的多态行为。