Reputation: 5528
I'm trying to organzine and reuse my reasonML code. I have model module types that look like the following:
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;
};
And I would like to generate a types and functions from the idType
s and schemaType
s.
examples are:
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)
};
So I'm attempting to construct a module using a functor passing each of the schemas through
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]; */
};
The code above didn't work. I'm having trouble adding module types to the model modules at the top. I also attempted through a SchemaType
module type but kept hitting The type idType is not a polymorphic variant type
, When I wanted each model to have distinct polymorphic variable types.
So overall, I want to know if it is possible to create a polymorphic variant type that can be created or extended using modules and functors?
If not is it possible to construct polymorphic variant types using a "list of modules"?
Thanks
Upvotes: 3
Views: 669
Reputation: 11637
Someone asked a similar question back in 2002. According to one of the OCaml language developers, it's not possible to dynamically extend polymorphic variant types like that: https://caml-list.inria.narkive.com/VVwLM96e/module-types-and-polymorphic-variants . The relevant bit:
The functor definition is refused because "The type M.t is not a polymorphic variant type" Is there a workaround?
Not that I know. Polymorphic variant extension only works for known closed variant types, otherwise it would not be sound.
The rest of the post has a suggestion which boils down to capturing the new variant types inside different tags, but again that wouldn't work for your use case of dynamically 'adding together' types using a functor.
Upvotes: 1
Reputation: 12342
For the types you can use an extensible variant type. But for the modelIdToIdFunction function given a list of modules I think you can only search through the list, which won't scale.
You should extend the uuid with an ID for each module so you can create a lookup table from module_id to the module from the list for fast access.
Upvotes: 0