“构造函数”的 OCaml 命名约定是什么?

vog*_*vog 3 ocaml conventions naming-conventions

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

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

StdLib 在这里不一致。例如:

  • Array.make一个已弃用的函数Array.create。那么该函数应该命名为make?
  • 另一方面,有Buffer.create但没有Buffer.make。那么该函数应该命名为create?

cam*_*ter 5

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

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

漂亮的命名空间

模块名称解释了它的类型和值是什么,因此您不需要在内部重复类型名称:Buffer.add_string而不是add_string_to_buffer,而Buffer.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 *)
Run Code Online (Sandbox Code Playgroud)

简单的 ML 函子应用

如果 ML 函子接受一个具有数据类型的参数模块,我们有一个约定,该类型应该被称为t。具有数据类型的模块t很容易应用于这些函子,而无需重命名类型。


对于Array.createand Array.make,我认为这是为了遵循String.createand的区分String.make

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

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

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

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

  • 作为母语人士,`create` 可能意味着更多的努力或从头开始生产,但这是一个非常小的内涵差异,它当然不会让我记住一个包括初始化。 (2认同)