为什么可以正常工作?
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
时打开模块?
提前感谢,
扎克
在第二个示例中,实际上根本不需要open Account
,语法只是`Current 100.0
。多态变体标签不参与任何特定类型。`Current
的类型是[> `Current ]
,这(>
)意味着类型至少是`Current
,并且由于这是函数接受的类型的子集,因此它可以很好地编译。您可以将相同的值传递给许多接受相同名称的多态变体的函数。当然,由于缺乏静态类型信息,输入错误和情况可能变得相当复杂。
通过多态变体的代码重用讨论了它们的一些优点和用例。
像`Current
这样的多态变量常量是全局定义的,类似于整数常量。你不能让Account.10
在Account
模块中引用整数10。
这是多态变体的优点(和缺点),你可以在不定义它们的情况下使用它们(就像你在使用它之前不必定义10)。
因此,正如nlucaroni所说,您不必打开Account
模块即可访问`Current
。
与整数不同,多态变体也可以接受参数(如您的`Current 100.0
)。但是参数的数量及其类型并不是固定的,对于代码中不同位置的同一个构造函数,它们甚至可能有所不同。因此,nlucaroni也提到了复杂性。
[格式说明:要在打字机样式的文本中显示单反引号`
,标记惯例是使用双反引号将文本括起来。这样在文本中只留下单个反引号。或者至少对我有用。[/p>