Module 是否可以对复合多态变体类型进行注释?

Module 是否可以对复合多态变体类型进行注释?,module,ocaml,reason,polymorphic-variants,Module,Ocaml,Reason,Polymorphic Variants,我一直在使用多态变量对结果类型(取自)进行错误处理,这对于彻底检查非常有用。我最近发现需要在函子中注释结果类型,但不确定这是否可行。这是一个片段,其中有一些关于我试图实现的目标的评论: 开放式皮带; /*这是一个快速的例子,说明我们现在的工作方式。这很好,而且 结果错误类型为[>`Error1 |`Error2]*/ 设res=Result.flatMap(Result.Error(`Error1),=>Result.Error(`Error2)); /*我们正在尝试做的事情的真正通用版本*/

我一直在使用多态变量对结果类型(取自)进行错误处理,这对于彻底检查非常有用。我最近发现需要在函子中注释结果类型,但不确定这是否可行。这是一个片段,其中有一些关于我试图实现的目标的评论:

开放式皮带;
/*这是一个快速的例子,说明我们现在的工作方式。这很好,而且
结果错误类型为[>`Error1 |`Error2]*/
设res=Result.flatMap(Result.Error(`Error1),=>Result.Error(`Error2));
/*我们正在尝试做的事情的真正通用版本*/
模块类型常规={
t型;
类型错误;
let res:Result.t(t,误差);
};
模块制造商=(M:通用)=>{
设res=M.res;
};
模块专用1=
制造({
类型t=字符串;
类型错误=[|`Specific1Error];
设res=Result.Error(`Specific1Error);
});
模块专用2=
制造({
类型t=int;
类型错误=[|`Specific2Error];
设res=Result.Error(`Specific2Error);
});
/*这肯定不会编译,因为这两种错误类型
不一样,但想知道上面的任何内容是否可以更改,以便
了解错误类型为[>`Specific1Error |`Specific2Error]*/
设res=Result.flatMap(Specific1.res,=>Specific2.res);

这不是一个完整的答案,但它提供了更多的信息和一个可能的解决方案或解决方法

通过向特定的组合类型添加显式强制,可以获得要编译的最后一行:

let res=
结果平面图(
Specific1.res:>Result.t(字符串,[`Specific1Error |`Specific2Error]),
_=>(Specific2.res:>Result.t(int,[`Specific1Error |`Specific2Error]);
在这里,他们都被强迫为同一类型,所以我们都很好。至于为什么它需要明确,我的理解是,这是为了防止错误输入构造函数的意外错误。更多信息请参阅

如果
type error
指定了下限,我们就不必显式,如下所示:

let error1:Result.t(int,[>`error1])=Result.Error(`error1);
设error2:Result.t(int,[>`error2])=Result.Error(`error2);
设res=Result.flatMap(error1,=>error2);
但是,由于上限和下限多态变量都有一个隐式类型变量,我们至少必须将
类型错误
更改为
类型错误('a)
。不幸的是,即使如此,我也不确定如何使模块签名与实现一致,因为,例如:

类型错误('a)=[>|`Specific1Error]as'a;
失败于

Signature mismatch:
...
Type declarations do not match:
  type 'a error = 'a constraint 'a = [> `Specific1Error ]
is not included in
  type 'a error
Their constraints differ.
This has type:
  (int, [ `Specific2Error ]) Result.t
But somewhere wanted:
  (int, [ `Specific1Error ]) Result.t
These two variant types have no intersection
也不可能强制使用下限多态性变体类型,我不确定这是为什么:

let res=
结果平面图(
Specific1.res:>Result.t(字符串,[>`Specific1Error]),
_=>(Specific2.res:>Result.t(int,[>`Specific2Error]));
失败于

Signature mismatch:
...
Type declarations do not match:
  type 'a error = 'a constraint 'a = [> `Specific1Error ]
is not included in
  type 'a error
Their constraints differ.
This has type:
  (int, [ `Specific2Error ]) Result.t
But somewhere wanted:
  (int, [ `Specific1Error ]) Result.t
These two variant types have no intersection
表示边界被忽略


我已经在几个方面达到了我的知识的极限,但我补充了你的问题,因为它有几个具有重要知识的追随者,有希望把最后的部分放在一起。

你为什么需要在
常规
模块签名中密封
错误
类型?由于在任何情况下,您都需要知道所有这些错误变量的总和,才能对最终的
res
值进行注释,因此您可以执行以下操作吗?(请原谅将其翻译成标准的OCaml语法和习惯用法。)


希望不会有一个单一的错误类型,包含所有可能的错误,您必须在每次处理这些错误时匹配这些错误。例如,如果你只使用Specific1.res,你只需要处理Specific1ErrorAh是的,我明白了。如果在那之前你没有得到更多关于这是否可行的专家指导,我会在我发生任何事情时更新。