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

时间:2011-10-27 15:35:41

标签: types ocaml variant

为什么这样可以正常使用?

module Account = struct

 type account_type = Current of float | Savings of float

end

let sarah = Account.Current 100.0;;

虽然下面的最后一行产生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;;

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

open Account;;
let pete = `Current 100.0;;

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

提前致谢,

扎克

2 个答案:

答案 0 :(得分:6)

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

Code Reuse through polymorphic variants讨论了它们的一些优点和用例。

答案 1 :(得分:5)

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

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

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

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

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