使用其他类型的变量列表定义类型

时间:2012-04-28 16:56:02

标签: module functional-programming ocaml functor

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

它可以是0到N种类型,因此是变量列表或集合

它看起来像这样:

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

当然我想将其创作分解

首先,我尝试创建一个由仿函数参数化的模块'Composite':

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

第一个难点:如何将变量的变量列表传递给'Composite'模块?

这是一个很好的方法吗?

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

2 个答案:

答案 0 :(得分:5)

如果想要一个“平面”复合类型并获得构造函数的联合,唯一的方法是使用多态变体(如注释中的@lukstafi所述),但在这种情况下,t1和t2不能是抽象的:

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 ]

如果你真的想使用模块,你必须松开你的平面表示,因此你将有一个不相交的联盟:

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

答案 1 :(得分:1)

我认为静态类型系统不允许你想要的东西。静态类型系统试图帮助您避免在某些功能中使用不正确类型而导致的错误。但在这里,您尝试定义一个具有 unknown * number *变体的类型。 OCAML不支持此功能。

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

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

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