在模块外部使用开放式联合,它们被定义为

ZJa*_*nes 5 ocaml types variant

为什么这样可以正常工作?

module Account = struct

 type account_type = Current of float | Savings of float

end

let sarah = Account.Current 100.0;;
Run Code Online (Sandbox Code Playgroud)

虽然下面的最后一行产生了Error: syntax error

module Account = struct

  type 'a account_type = [> `Current of float | `Savings of float ] as 'a

end

let pete = Account.`Current 100.0;;
Run Code Online (Sandbox Code Playgroud)

也就是说,为什么我不能在不打开模块的情况下在模块外部使用open union类型?我应该说我发现将最后一行更改为:

open Account;;
let pete = `Current 100.0;;
Run Code Online (Sandbox Code Playgroud)

工作正常,但显然这很麻烦,如果我account_type经常使用,或者我必须Account在使用的任何代码部分的开头打开account_type,这意味着我牺牲了我通过使用签名获得的抽象Account
我'已经浏览了几个OCaml教程以及INRIA文档,我找不到你如何做到这一点.
是否有可能避免每次我想使用时都打开模块account_type

提前致谢,

扎克

nlu*_*oni 6

在第二个例子中,你实际上根本不需要open Account,语法就是这样`Current 100.0.多态变体标签不参与任何特定类型.`Currentis 的类型[> `Current ],this(the >)表示类型至少是`Current,并且因为它是函数接受的类型的子集,所以它将编译得很好.您可以将相同的值传递给许多接受同名多态变体的函数.当然,缺少静态类型信息,键入错误和情况可能变得非常复杂.

通过多态变体重用代码可以讨论它们的一些优点和用例.


Jef*_*eld 5

`Current整数常量一样,多态变体常量是全局定义的.你不会说Account.10Account模块中引用整数10 .

这是多态变体的强度(和弱点),您可以在不定义它们的情况下使用它们(就像在使用它之前不必定义10).

因此,正如nlucaroni所说,您无需打开Account模块即可访问`Current.

与整数不同,多态变体也可以采用参数(如您的`Current 100.0).但是参数的数量和它们的类型并不固定,它们甚至可以在代码中的不同位置对于相同的构造函数而变化.因此nlucaroni也提到了复杂性.

[格式化注释:为了使单个反引号`显示在打字机样式的文本中,降价约定是使用加倍的反引号来包含文本.这会在文本中留下单个反引号.或者至少它对我有用.]