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

How to define an abstract (opaque) interface for a polymorphic object type?

原因ML

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;
};

Ocaml

module type T  = sig
  type 'a t /* Doesn't work */
  type b /* Works */
end
module A : T = struct type 'a t = < b :bool  ;.. > as 'a
                      type b = bool end 
module B : T = struct type 'a t = < c :int  ;.. > as 'a
                      type 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

类型 <b : bool; .. ><c : int; ..> 不兼容,就像 intbool 不兼容一样。换句话说,如果我们将 aside, and focus on simple type constructors, then you're trying to define an interface that matches type int and bool and nothing else, aka bounded polymorphism.

理解 subtyping is not inheritance 也很重要。在您的情况下,您有两个 class 对象,b-class 对象具有方法 b

class virtual b = object
  method virtual b : bool
end

和具有方法 c

的对象的 c- class

class virtual c = object
  method virtual c : int
end

我们可以定义一个 class 的对象 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 class 类型被定义为继承自 b 和 c 我们不能将 b 强制转换为 c,

# (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

这很有意义,因为我们试图将基 class 的对象向下转换为派生 class 的对象,这是非法操作。因此,当您具有按继承排序的 class 类型的层次结构时,基础 classes 是超类型,派生的 classes 是子类型。例如,如果 v 继承自 u,则 vu

的子类型
v inherits-from u
-----------------
   u :> v

明白了这一点,就可以设计合适的界面了。