【问题标题】:Defining a type with a variable list of other types使用其他类型的变量列表定义类型
【发布时间】:2012-05-09 02:03:18
【问题描述】:

我想编写一个模块(在 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 或两者)?

【问题讨论】:

  • 我不是模块和函子类型方面的专家(委婉地说),但在我看来,你正在与类型系统作斗争,以产生你已经可以用 @987654324 做的事情@.
  • 我不认为您可以创建具有可变数量构造函数的类型,也不能创建具有可变数量参数的仿函数。但是,根据您的用例,可能会有更好的方法;换句话说:你真的需要那个吗?
  • Polymorphic variants 在模块系统之外,但它们最接近“现有构造函数的聚合”。
  • 好的,所以模块不适合这里?但是,如何在复合类型上定义一组函数?

标签: module functional-programming ocaml functor


【解决方案1】:

如果想要一个“平面”复合类型并获得构造函数的联合,唯一的方法是使用多态变体(如 @lukstafi 在 cmets 中所述),但在这种情况下 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

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多