"constructors" 的 OCaml 命名约定是什么?

What's the OCaml naming convention for "constructors"?

一个OCaml模块通常至少包含一个抽象类型,其惯用名称是t。此外,通常有一个函数可以构造该类型的值。

这个的常用/惯用名称是什么?

这里的标准库不一致。例如:

我很久以前学习这门语言时也有过同样的问题。我从不使用 make,而且我认为很少有人使用。

如今,我将 create 用于繁重的、通常是命令式或有状态的值,例如Unicode text segmenter. And I use v for, functional, lighter values in DSL/combinator based settings, e.g. the various constructors in Gg, for example for 2D vectors, or colors.

正如 camlspotter 在他的回答中提到的那样,标准库将 makecreate 区分为需要填写初始值的值。我认为最好在这里保持常规并始终使用 create 不管怎样。如果您的值支持可选的初始填充值,请向 create 添加一个可选参数,而不是乘以 API 入口点。

有些人发现这种模块设计方式使 OCaml 编程更容易,但这不是强制性的 OCaml 编程风格,我认为它没有正式名称。我个人称其为“1-data-type-per-1-module”风格。 (我写了a blog post about this但是是日文的,希望有自动翻译器能给你一些有用的信息...)

定义一个专用于一种数据类型的模块并修复该类型的名称t有一些值:

不错的命名空间

模块名称解释了它的类型和值是什么,因此您不需要在内部重复类型名称:Buffer.add_string 而不是 add_string_to_bufferBuffer.create 而不是 create_buffer。您还可以避免在本地模块打开时键入相同的模块名称:

let f () =
  let open Buffer in
  let b = create 10 in   (* instead of Buffer.create *)
  add_string b "hello";  (* instead of Buffer.add_string *)
  contents b             (* instead of Buffer.contents *)

简单的 ML 函子应用程序

如果 ML 仿函数采用具有数据类型的参数模块,我们有一个约定,该类型应该被称为 t。数据类型为 t 的模块无需重命名类型即可轻松应用于这些函子。


对于Array.createArray.make,我认为这是为了区分String.createString.make

  • String.create是创建一个未初始化内容的字符串。创建的字符串包含随机字节。
  • String.make 是创建一个用给定的 char.
  • 填充的字符串

我们已经 Array.create 很久了,以创建一个数组,其内容填充给定值。此行为对应于 String.make 而不是 String.create。这就是为什么它现在重命名为 Array.make,而 Array.create 已过时。

我们不能在 OCaml 中让 Array.create 具有与 String.create 相同的行为。与字符串不同,数组不能在没有初始化的情况下创建,因为随机字节通常可能不代表内容的有效 OCaml 值,这会导致程序崩溃。

在此之后,我个人使用 X.create 作为函数来创建一个不需要初始值来填充的 X.t。如果需要填充,我使用 X.make