哪种语言的泛型是泛型 类 并且 OCaml 中的函数类似于 C++、Java 或 C#?
Which language's generics are generic classes and functions in OCaml similar to, C++, Java or C#?
我从 了解了 C++ 模板、Java 泛型和 C# 泛型之间的区别,这有助于我更好地理解如何以不同的方式正确使用它们。
OCaml中的类也可以有类型参数,见https://realworldocaml.org/v1/en/html/classes.html中的"Class Parameters and Polymorphism"。
如果我是对的,在OCaml中,虽然类可以显式参数多态,functions隐式参数多态?
为了帮助我学习在 OCaml 中使用泛型,哪种语言的泛型是泛型 类 并且 OCaml 中的函数类似于 C++、Java 或 C#?我是否正确,因为 OCaml 的函数是隐式参数多态的而不是显式的,而 C++ 中的泛型函数,Java 和 C# 是显式参数多态的,它们根本不相似?
OCaml 似乎有第三个泛型:generic modules called functors。如果我是正确的,泛型模块不同于泛型 类 和 OCaml 中的函数。我这里的问题只是关于 类 和功能。
谢谢。
TL;DR; Java 是最接近的。
OCaml 类型系统以注释的形式提供了parametric polymorphism, that means that a type of value can have type variables (parameters), meaning that a value can have multiple types in a given context. Unlike languages that you mentioned, OCaml also has type inference. OCaml will infer the most general type of value, based on how the value is used in a program, i.e., it will try to find the biggest set of types that match the usage of the value. The property of a type inference system to be able to derive the most general type (the biggest set of types - also called the principal type), is called principality. OCaml uses a type-inference system that is based on Hindley-Milner type system, though it went much father. First of all, OCaml has subtyping, and type inference (that tries to be principal) with subtyping requires 程序员的一些帮助(否则它会推断出不太通用的类型)。这就是 OCaml 类 具有显式类型参数的原因。如果我们忘记子类型化,那么 类、对象、函数甚至函子都可以被认为是相等的。事实上,它们基本上具有相同的运行时表示。在 OCaml 中,我们不区分显式和隐式类型变量。一种类型的函数也有类型变量,但由于编译器通常会为我们推断类型,所以我们不指定它们。然而,当我们定义模块接口时,我们总是显式指定类型变量,例如,考虑 List
模块提供具有类型 'a list -> int
的 length
函数。如您所见,类型变量 'a
在这里非常明确。
关于表示,Java表示是实现参数多态性的正确方式。正如参数多态性所说的那样,一个值具有多种类型,而不是具有不同类型的一系列值(它们是在运行时还是在编译时构造的并不重要)。这显示了 C#/C++ 泛型和 OCaml/Java 泛型之间的本质区别。在后者中,我们有一个通用的值,而在前者中,我们有一个具有相同接口但可能有不同实现的值工厂,这实际上是 ad hoc polymophism 的一个例子。所以,在 OCaml 中,当你有一个多态函数或一个数据值时,它总是只有一个对象,无论它应用在哪里,例如,在 List.length [1;2;3]
和 List.length ["hello"; "world"]
中 List.length
函数应用于不同的列表。
我从
类也可以有类型参数,见https://realworldocaml.org/v1/en/html/classes.html中的"Class Parameters and Polymorphism"。
如果我是对的,在OCaml中,虽然类可以显式参数多态,functions隐式参数多态?
为了帮助我学习在 OCaml 中使用泛型,哪种语言的泛型是泛型 类 并且 OCaml 中的函数类似于 C++、Java 或 C#?我是否正确,因为 OCaml 的函数是隐式参数多态的而不是显式的,而 C++ 中的泛型函数,Java 和 C# 是显式参数多态的,它们根本不相似?
OCaml 似乎有第三个泛型:generic modules called functors。如果我是正确的,泛型模块不同于泛型 类 和 OCaml 中的函数。我这里的问题只是关于 类 和功能。
谢谢。
TL;DR; Java 是最接近的。
OCaml 类型系统以注释的形式提供了parametric polymorphism, that means that a type of value can have type variables (parameters), meaning that a value can have multiple types in a given context. Unlike languages that you mentioned, OCaml also has type inference. OCaml will infer the most general type of value, based on how the value is used in a program, i.e., it will try to find the biggest set of types that match the usage of the value. The property of a type inference system to be able to derive the most general type (the biggest set of types - also called the principal type), is called principality. OCaml uses a type-inference system that is based on Hindley-Milner type system, though it went much father. First of all, OCaml has subtyping, and type inference (that tries to be principal) with subtyping requires 程序员的一些帮助(否则它会推断出不太通用的类型)。这就是 OCaml 类 具有显式类型参数的原因。如果我们忘记子类型化,那么 类、对象、函数甚至函子都可以被认为是相等的。事实上,它们基本上具有相同的运行时表示。在 OCaml 中,我们不区分显式和隐式类型变量。一种类型的函数也有类型变量,但由于编译器通常会为我们推断类型,所以我们不指定它们。然而,当我们定义模块接口时,我们总是显式指定类型变量,例如,考虑 List
模块提供具有类型 'a list -> int
的 length
函数。如您所见,类型变量 'a
在这里非常明确。
关于表示,Java表示是实现参数多态性的正确方式。正如参数多态性所说的那样,一个值具有多种类型,而不是具有不同类型的一系列值(它们是在运行时还是在编译时构造的并不重要)。这显示了 C#/C++ 泛型和 OCaml/Java 泛型之间的本质区别。在后者中,我们有一个通用的值,而在前者中,我们有一个具有相同接口但可能有不同实现的值工厂,这实际上是 ad hoc polymophism 的一个例子。所以,在 OCaml 中,当你有一个多态函数或一个数据值时,它总是只有一个对象,无论它应用在哪里,例如,在 List.length [1;2;3]
和 List.length ["hello"; "world"]
中 List.length
函数应用于不同的列表。