Ocaml 如何为多态对象类型定义抽象(不透明)接口?

Ocaml 如何为多态对象类型定义抽象(不透明)接口?,ocaml,reason,rescript,Ocaml,Reason,Rescript,理由 module type T = { type t('a); // Does not work type b; // Works }; module A: T = { type t('a) = {.. b: bool} as 'a; type b = bool; }; module B: T = { type t('a) = {.. c: int} as 'a; type b = int; }; 奥卡姆 模块类型T=sig 输入'a t/*无效*/ b类/*工程*

理由

module type T = {
  type t('a); // Does not work
  type b; // Works
};

module A: T = {
  type t('a) = {.. b: bool} as 'a;
  type b = bool;
};
module B: T = {
  type t('a) = {.. c: int} as 'a;
  type b = int;
};
奥卡姆

模块类型T=sig
输入'a t/*无效*/
b类/*工程*/
结束
模块A:T=struct type'at=作为一个
b型=布尔端
模块B:T=struct type'at=作为一个
类型b=int-end

如何定义模块类型A t('A),使其抽象但与实现中的开放多态对象类型兼容?

不清楚它是否真的有用,但您需要在模块类型中明确添加约束:

module type TA  = sig
  type 'a t constraint 'a = < b:bool; .. >
end
module A : TA = struct
  type 'a t = < b :bool  ;.. > as 'a
end
模块类型TA=sig
键入'a t constraint'a=
结束
模块A:TA=struct
键入'at=作为一个
结束

不清楚它是否真的有用,但您需要在模块类型中明确添加约束:

module type TA  = sig
  type 'a t constraint 'a = < b:bool; .. >
end
module A : TA = struct
  type 'a t = < b :bool  ;.. > as 'a
end
模块类型TA=sig
键入'a t constraint'a=
结束
模块A:TA=struct
键入'at=作为一个
结束
类型
不兼容,就像
int
bool
不兼容一样。换句话说,如果我们把注意力放在简单的类型构造函数上,那么您正试图定义一个与类型
int
bool
匹配的接口,而不是其他的接口

理解这一点也很重要。在本例中,您有两类对象,
b
-类对象具有方法
b

class virtual b = object
  method virtual b : bool
end
以及
c
-具有方法
c
的对象类


class virtual c = object
  method virtual c : int
end
# (b : b :> bc);;
Line 1, characters 0-13:
1 | (b : b :> bc);;
    ^^^^^^^^^^^^^
Error: Type b = < b : bool > is not a subtype of bc = < b : bool; c : int > 
       The first object type has no method c
我们可以定义一类对象
bc
,这两种方法都有,自然通过继承

class virtual bc = object
  inherit b
  inherit c
end
现在,让我们做一些东西来玩

let b : b = object method b = true end
let c : c = object method c = 42 end
let bc : bc = object
  method b = false
  method c = 56
end

我们可以看到,尽管
bc
类类型被定义为继承自b和c,但我们不能强制
b
c


class virtual c = object
  method virtual c : int
end
# (b : b :> bc);;
Line 1, characters 0-13:
1 | (b : b :> bc);;
    ^^^^^^^^^^^^^
Error: Type b = < b : bool > is not a subtype of bc = < b : bool; c : int > 
       The first object type has no method c
一旦你明白了这一点,你就可以设计一个合适的界面。

类型
不兼容,就像
int
bool
不兼容一样。换句话说,如果我们把注意力放在简单的类型构造函数上,那么您正试图定义一个与类型
int
bool
匹配的接口,而不是其他的接口

理解这一点也很重要。在本例中,您有两类对象,
b
-类对象具有方法
b

class virtual b = object
  method virtual b : bool
end
以及
c
-具有方法
c
的对象类


class virtual c = object
  method virtual c : int
end
# (b : b :> bc);;
Line 1, characters 0-13:
1 | (b : b :> bc);;
    ^^^^^^^^^^^^^
Error: Type b = < b : bool > is not a subtype of bc = < b : bool; c : int > 
       The first object type has no method c
我们可以定义一类对象
bc
,这两种方法都有,自然通过继承

class virtual bc = object
  inherit b
  inherit c
end
现在,让我们做一些东西来玩

let b : b = object method b = true end
let c : c = object method c = 42 end
let bc : bc = object
  method b = false
  method c = 56
end

我们可以看到,尽管
bc
类类型被定义为继承自b和c,但我们不能强制
b
c


class virtual c = object
  method virtual c : int
end
# (b : b :> bc);;
Line 1, characters 0-13:
1 | (b : b :> bc);;
    ^^^^^^^^^^^^^
Error: Type b = < b : bool > is not a subtype of bc = < b : bool; c : int > 
       The first object type has no method c

一旦您清楚地了解了这一点,就可以设计一个合适的接口。

TA如何与模块B兼容?例如,我想实现一个与函子一起使用的接口(类型类),模块a或B可以传入,但不能。
a
B
中对类型参数
'a
的约束相互不兼容。TA如何与模块B兼容?例如,我想实现一个与函子一起使用的接口(类型类),模块a或B可以传入,但不能。
a
B
中对类型参数
'a
的约束相互不兼容。我知道a.t和B.t是不兼容的,但如何定义兼容的抽象接口?例如,bool和int是不兼容的,但我仍然可以在接口中定义类型b。如果我们完全删除模块B,代码仍然无法编译。考虑到最初的设计约束,没有这样的接口。这就是我和@octachron想要说的。因此,您需要重新思考为什么会出现不兼容的接口,或者发布另一个问题来描述您最初的问题。考虑到状态的方式,答案很简单-不,没有这样的模块类型,也不应该。我理解A.t和B.t是不兼容的,但我如何定义一个兼容的抽象接口?例如,bool和int是不兼容的,但我仍然可以在接口中定义类型b。如果我们完全删除模块B,代码仍然无法编译。考虑到最初的设计约束,没有这样的接口。这就是我和@octachron想要说的。因此,您需要重新思考为什么会出现不兼容的接口,或者发布另一个问题来描述您最初的问题。考虑到它的状态,答案很简单-不,没有这样的模块类型,不应该。