如何为多态对象类型定义抽象(不透明)接口?
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; ..>
不兼容,就像 int
和 bool
不兼容一样。换句话说,如果我们将 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
,则 v
是 u
、
的子类型
v inherits-from u
-----------------
u :> v
明白了这一点,就可以设计合适的界面了。
原因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; ..>
不兼容,就像 int
和 bool
不兼容一样。换句话说,如果我们将 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
,则 v
是 u
、
v inherits-from u
-----------------
u :> v
明白了这一点,就可以设计合适的界面了。