OCaml多态性的例子,而不是模板函数

OCaml polymorphism example other than template function?

本文关键字:函数 多态性 OCaml      更新时间:2023-10-16

我想自己理解一下,OCaml语言有哪种形式的多态。

我是由一个例子提供的

let id x = x

这个例子是不是等价于c++的模板函数

template<class A> A id(A x) { return x; }

如果是这样,那么我的问题是:在OCaml中有任何其他形式的多态性吗?这个概念在命令式语言的世界里被称为"泛型算法",而不是"多态性"。

基本上有三种语言特性有时被称为多态性:

  • 参数多态性(即"仿制药")
  • 子类型多态性,这是类型的子类型提供比超类型更具体的操作版本的能力,即覆盖方法的能力(以及运行时系统根据对象的运行时类型调用方法的正确实现的能力)。在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)

打印4

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

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

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

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

let swap ((x : 'a), (y : 'b)) : 'b * 'a = (y, x)

这样无论'a'b是什么类型都可以工作

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