1

我想编写一个模块(在 Ocaml 3.12 中)能够将 Variant 类型定义为现有不同类型的聚合

它可以是 0 到 N 种类型,所以是一个变量列表或集合

它可能看起来像这样:

type newtype = Type0 of type0 | Type1 of type1 | ... | TypeN of typeN

当然我想分解它的创造

首先,我尝试创建一个由仿函数参数化的模块“复合”:

module Composite ( T0 : sig type t end ) ( T1 : sig type t end ) = 
struct
  type t = T0.t | T1.t
end

第一个困难:如何将一个可变的函子列表传递给“复合”模块?

这是进行的好方法吗?

edit1 : Variant 允许定义 XOR 类型定义(它是 T0 或 T1 但不是两者);如何定义 OR 类型定义(可以是 T0 或 T1 或两者)?

4

2 回答 2

5

If want a "flat" composite type and get the union of constructors, the only way is to use polymorphic variants (as stated by @lukstafi in the comments), but in this case t1 and t2 cannot be abstract:

type t1 = [ `A of int | `B of string | `C of float ]
type t2 = [ `B of string | `C of float | `D of char ]
type t3 = [ t1 | t2 ]

If you really want to use modules you have to loose your flat representation and thus you will have a disjoint union:

module Composite ( T0 : sig type t end ) ( T1 : sig type t end ) = 
struct
  type t = T0 of T0.t | T1 of T1.t
end
于 2012-04-30T08:12:35.327 回答
1

我认为静态类型系统不允许你想要什么。静态类型系统试图帮助您避免因在某些函数中使用不正确类型而导致的错误。但是在这里,您试图定义一种具有未知*number* 变体的类型。这在 OCAML 中不受支持。

出于同样的原因,不支持异构列表和元素数量未知的元组。

对于您的第二个问题:对象不能属于“T1 和 T2”类型,其中 T1 和 T2 是未知类型......这个概念与类型检查不兼容。如果 T1 和 T2 是兼容类型,即 T2 是从 T1 继承的对象类型,或者 T2 是作为 T1 扩展的多态变体类型,那么你可以拥有 T1 类型的对象,也可以将 T2 强制转换为 T1 . 但是仍然没有“T1和T2”的概念。如果你有一个只接受 T1 的函数,如果给定一个类型为“T1 和 T2”但不仅仅是“T1”的对象,这个函数应该怎么做?我认为没有答案。

尽管 OCAML 不支持这些东西,但您可能可以以不同的方式设计您的类型,以便 OCAML 的类型系统接受您的代码。OCAML 的类型系统非常灵活,它可以帮助您避免代码中的错误!

于 2012-04-30T08:55:40.583 回答