在OCaml中,是否有一种简单的构造/风格来扩展已定义的类型?
比如说,如果我们有布尔类型。
bool2 = True | False
现在我们想将它扩展为3值逻辑。在Ocaml中,是否有比像这样重新定义bool2更优雅的方法:
bool3 = True | False | ThirdOne
多态变量提供了这个功能:
type bool2 = [ `True | `False ]
type bool3 = [ bool2 | `Third_one ]
就是这样。
对于多态变体,还有另一个有用的快捷方式。在模式匹配中,使用类型名称前缀#
:
let is_bool2 = function
#bool2 -> true
| `Third_one -> false
使用多态变体时应谨慎,因为它们很容易导致混淆的错误消息。如果原始类型bool2
不是多态变体,则可以通过以下方式实现两种类型的联合。假设bool2
是核心类型bool
,我们使用经典变体进行定义:
type bool3 = Bool of bool | Third_one
在模式匹配中,编译器将检查所有情况是否都被覆盖,而无需要求类型注释。代码如下:
match x with | Bool true -> ... | Bool false -> ... | Third_one -> ...
| Third_one -> assert false
),然后您就有了可编译的代码,并且可以在应用程序测试期间发生运行时故障时进行纠正。但我仍然认为静态编译器反馈对于代码维护是很有帮助的。type bool3 = New | Old of bool2
中,在Martin的答案评论中讨论了这一点。这可能是一种好的过渡方式,从一个数据类型转换到另一个数据类型而不会破坏编译,但从长远来看这是痛苦的,特别是如果您在其上堆叠更多的扩展。