是否可以使用模块动态创建多态变体类型?

时间:2018-12-01 20:08:56

标签: ocaml variant strong-typing reason polymorphic-variants

我正在尝试整理并重用我的reasonML代码。我的模型模块类型如下所示:

module Diet = {

  type schemaType = [`DietSchema];
  type idType = [`DietId(UUID.t)];

  let schema = `DietSchema;
  type idAsType('a) = [> | idType] as 'a;     
};

module Ingredient = {
  type schemaType = [`IngredientSchema];
  type idType = [`IngredientId(UUID.t)];

  let schema = `IngredientSchema;
  type idAsType('a) = [> | idType] as 'a;
};

module Restriction = {
  type schemaType = [`RestrictionSchema];
  type idType = [`RestrictionId(UUID.t)];

  let schema = `RestrictionSchema;
  type idAsType('a) = [> | idType] as 'a;
};

我想从idTypeschemaType生成类型和函数。

示例是:

type modelIdType = [
  | Diet.idType
  | Restriction.idType
  | Ingredient.idType
];

type schemaType = [
  | Diet.schemaType
  | Restriction.schemaType
  | Ingredient.schemaType
];

let modelIdToIdFunction = (recordIdType): (schemaType, UUID.t) =>
  switch (recordIdType) {
  | `DietId(uuid) => (Diet.schema, uuid)
  | `RestrictionId(uuid) => (Restriction.schema, uuid)
  | `IngredientId(uuid) => (Ingredient.schema, uuid)
  };

所以我试图使用传递每个模式的函子构造模块

module Diet : SchemaType = {
  /* ... */
};

module type SchemaType {
  type schemaType;
  type idType;

  let schema: [> schemaType];
  type idAsType('a) = [> | idType] as 'a;
};

module ProcessSchema = (
  Schema : SchemaType,
  PrevFullSchema : FullSchema
) : (FullSchema) => {
  type id = [> Schema.idType' | PrevFullSchema.id'('a)]  as 'a;
  /* type id = [PrevFullSchema.openId(PrevFullSchema.id) | Schema.idType]; */
  /* type schema = [PrevFullSchema.schema | Schema.schema]; */
  /* type openSchema = [PrevFullSchema.schema | Schema.schema]; */
};

以上代码无效。我在顶部的模块模块中添加模块类型时遇到麻烦。当我希望每个模型都具有不同的多态变量类型时,我还尝试了SchemaType模块类型,但一直按The type idType is not a polymorphic variant type

总的来说,我想知道是否可以创建可以使用模块和函子创建或扩展的多态变体类型吗?

是否可以使用“模块列表”来构造多态变体类型?

谢谢

2 个答案:

答案 0 :(得分:1)

有人在2002年问过类似的问题。据OCaml语言开发人员之一说,不可能像这样https://caml-list.inria.narkive.com/VVwLM96e/module-types-and-polymorphic-variants动态扩展多态变体类型。相关位:

  
    

函子定义被拒绝,因为     “类型M.t不是多态变体类型”     有解决方法吗?

  
     

我不知道。多态变体扩展仅适用于已知   封闭的变体类型,否则将不会发出声音。

该帖子的其余部分有一个建议,可以归结为捕获不同标签内的新变体类型,但是对于您使用仿函数动态“加在一起”类型的用例,同样如此。

答案 1 :(得分:0)

对于类型,您可以使用可扩展的变体类型。但是对于给定的模块列表的modelIdToIdFunction函数,我认为您只能在列表中进行搜索,而无法缩放。

您应该为每个模块扩展一个带有ID的uuid,以便您可以从list_id到列表中的模块创建一个查找表,以便快速访问。