ReasonML
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
How can I define the module type A t('a) so that it is abstract but compatible with the open polymorphic object types in the implementations?
Types
<b : bool; .. >
and<c : int; ..>
are not compatible much likeint
andbool
are not compatible. In other words, if we will put row polymorphism aside, and focus on simple type constructors, then you're trying to define an interface that matches typeint
andbool
and nothing else, aka bounded polymorphism.It is also important to understand that subtyping is not inheritance. In your case, you have two classes of objects, the
b
-class objects that have methodb
and the
c
- class of objects that have methodc
,and we can define a class of objects
bc
that have both methods, naturally via inheritance,Now, let's cooks some objects to play with,
We can see that despite that
bc
class type is defined as inherited from b and c we can't coerceb
toc
,and this makes perfect sense since we're trying to downcast an object of the base class to an object of the derived class, which is an illegal operation. Therefore, when you have a hierarchy of class types ordered by inheritance, the base classes are super types and the derived classes are subtypes. E.g., if
v
inherits fromu
thenv
is a subtype ofu
,Once you get a clear understanding of this, you can design a proper interface.