OCaml模块通常包含至少一个其惯用名称为t
的抽象类型。此外,通常还有一个函数构造该类型的值。
通常/惯用的名称是什么?
StdLib在这里并不一致。例如:
Array.make
和已弃用的函数Array.create
。那么该函数应该命名为make
?Buffer.create
但不是Buffer.make
。那么该函数应该命名为create
?答案 0 :(得分:4)
有些人发现这种模块设计方式使OCaml编程更容易,但这不是强制性的OCaml编程风格,我认为它没有正式的名称。我个人称之为" 1-data-type-per-1-module"样式。 (我写了a blog post about this但它是日文的。我希望有些自动翻译器能为你提供一些有用的信息......)
定义专用于一种数据类型的模块并修复类型t
的名称有一些值:
模块名称解释了它的类型和值是什么,因此您不需要在内部重复类型名称:Buffer.add_string
而不是add_string_to_buffer
和Buffer.create
而不是{{1} }。您还可以避免在本地模块打开的情况下键入相同的模块名称:
create_buffer
如果ML仿函数采用带有数据类型的参数模块,我们有一个约定,该类型应该被称为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 *)
。数据类型为t
的模块很容易应用于这些仿函数,而无需重命名类型。
对于t
和Array.create
,我认为这是遵循Array.make
和String.create
的区别。
String.make
是创建一个包含未初始化内容的字符串。创建的字符串包含随机字节。String.create
是创建一个用给定String.make
填充的字符串。我们长时间char
,创建一个内容用给定值填充的数组。此行为与Array.create
相对应,而不是String.make
。这就是为什么它现在已重命名为String.create
,而Array.make
已过时。
我们不能在OCaml中Array.create
使用Array.create
的相同行为。与字符串不同,不能在没有初始化的情况下创建数组,因为随机字节通常不代表内容的有效OCaml值,这会导致程序崩溃。
在此之后,我个人使用String.create
来创建一个X.create
函数,该函数不需要初始值来填充它。如果需要填写内容,我会使用X.t
。
答案 1 :(得分:1)
很久以前,当我拿起语言时,我遇到了同样的问题。我从不使用make
,我认为很少有人这样做。
现在我使用create
来表示繁重的,通常是命令式的或有状态的值,例如一个Unicode text segmenter。并且我在基于DSL /组合器的设置中使用v
来表示功能较轻的值,例如Gg中的各种构造函数,例如2D vectors或colors。
正如camlspotter在他的回答中提到的那样,标准库将make
和create
区分为需要填写初始值的值。我认为最好在这里定期并始终使用{{1} } 而不管。如果您的值支持可选的初始填充值,请向create
添加可选参数,而不是将API入口点相乘。