Types 重用和扩展Ocaml中定义的类型

Types 重用和扩展Ocaml中定义的类型,types,ocaml,extend,Types,Ocaml,Extend,在Ocaml中,是否有一个简单的构造/样式来扩展定义的类型 如果我们有布尔类型 bool2 = True | False 现在我们想把它扩展到三值逻辑。在Ocaml中,还有比重新定义bool2更优雅的吗 bool3 = True | False | ThirdOne 多态变体提供以下功能: type bool2 = [ `True | `False ] type bool3 = [ bool2 | `Third_one ] 就这样 多态变体还有另一个有用的快捷方式。在模式匹配中,使用前面

在Ocaml中,是否有一个简单的构造/样式来扩展定义的类型

如果我们有布尔类型

bool2 = True | False 
现在我们想把它扩展到三值逻辑。在Ocaml中,还有比重新定义bool2更优雅的吗

bool3 = True | False | ThirdOne

多态变体提供以下功能:

type bool2 = [ `True | `False ]
type bool3 = [ bool2 | `Third_one ]
就这样

多态变体还有另一个有用的快捷方式。在模式匹配中,使用前面带有
#
的类型名称:

多态变体应谨慎使用,因为它们很容易导致混淆错误消息。如果原始类型
bool2
无论如何都不是多态变体,则两个类型的联合实现如下。假设
bool2
是核心类型
bool
,我们使用经典变体的定义是:

type bool3 = Bool of bool | Third_one 类型bool3=Bool的Bool |第三个 在模式匹配中,编译器将检查是否涵盖了所有情况,而不需要类型注释。看起来是这样的:

match x with | Bool true -> ... | Bool false -> ... | Third_one -> ... 将x与 |布尔真->。。。 |布尔假->。。。 |第三个-->。。。
我建议不要过度使用多态变体。它们在纸上看起来不错,但更灵活的推理和子类型在任何时候都会咬到你。当我使用多态变量时,我试图确保每次使用都使用精确的约束类型表达式进行注释

我建议回去修改您的旧代码,这似乎很自然。如果您在编写代码时考虑到了可扩展性,特别是在
bool2
类型上避免了
\ucode>-模式,那么编译器将警告您任何假设只有两个构造函数的地方。这个编译器关于类型修改的反馈非常有用,因为它是使程序正确的机械帮助

这种做法当然有一些缺点。其中之一是修改类型定义,然后修改每个用例可能不适合您通常的编译测试实践:如果您在大型代码库上这样做,那么在您的项目再次干净地编译(因此可以进行测试)之前,您将有大量的事情要做。您可以在版本控制系统的几个补丁中分割修改,但这意味着一些中间提交状态不会编译,这不是很令人满意。另一种可能是只更改这些位置以添加运行时故障(
| Third_one->assert false
),这样您就有了可编译的代码,并且可以在测试应用程序的运行时纠正这些故障。但我仍然认为静态编译器反馈对代码维护有很好的帮助

还可以选择将代数数据类型包装为“扩展代数数据类型”
type bool3=New | Old of bool2
,这将在您作为Martin answer注释给出的链接中讨论。这可能是一种在不破坏编译的情况下从一种数据类型转换到另一种数据类型的好方法,但从长远来看,这是一种痛苦的经历,尤其是如果您将更多的扩展堆叠在彼此之上

当然,在某些情况下,真正需要的是一种通过添加代码而不是修改代码来扩展数据类型的方法,这种方法既静态安全,更易于编译、运行和测试,又在运行时高效。这是的一个实例,它们是各种解决方案,多态变体就是其中之一。但在一般情况下,您不需要仅进行代码添加的额外灵活性,而且不值得相关语言特性的额外复杂性,因此我建议您坚持使用普通的旧变体类型,除非明显地可以从中获得巨大的好处


PS:关于多态性变体及其与表达问题的关系,这篇必修论文由Jacques Garrigue撰写。

根据手头的任务,您可能会发现有用的信息。更多信息和用例

类型bool=。。
类型布尔+=
|真的
|假的
(*其他地方*)
类型布尔+=
|三一

Imagine bool2是库中定义的一种类型。显然,通过多态变体提出的方法要求我们重新定义bool2的原始定义,从单多形定义到多态定义。所以我想对我的问题的一个简短的直接回答是:不,我们确实需要重新定义bool2,以便将其扩展到bool3。对吧,马丁?谢谢。哦,我在网上发现了一个非常类似的问题。 match x with | Bool true -> ... | Bool false -> ... | Third_one -> ...