Can I generically extend Classes and Polymorphic Variants via Functors?

I’d like to do something akin to this

    module type SINATURA = sig
        type ('a) msg (*this should be constraint to a (any) polymorphic variant *)
        type ('a) action (*this should be constraint to a (any) class *)
    end

    module Z (M1: SINATURA) = struct
        type real_msg = [`some_id | string M1.msg ]
        class real_cls =
            object
            inherit int M1.action
        end
    end

obviously (sadly?) I get error on both real_msg and real_cls

I don’t understand what you are trying to do.
The real_msg will fail because the type you are adding is not a polymorphic variant, it should work if you do something like

type real_msg = [`some_id | `s of string M1.msg ]

while real_cls seems to be trying to inherit from a type. I am not familiar with ocaml objects but I think in that case it is a matter of comparing oranges with apples.

An easy solution is to use composition rather than trying to extend abstract classes and polymorphics variants:

   module Z (M1: SINATURA) = struct
        type real_msg = [`some_id | `M1 of string M1.msg ]
        class['a] real_cls (x: 'a M1.action) =
            object
            method m1= x
           ...
        end
    end

Otherwise, it is not possible to extend unknown classes and polymorphic variants, as it would require a kind system that does not exist in OCaml. Indeed, the notion of any polymorphic variants or any classes reduces to the empty polymorphic variant [ ] and the empty classes object end. Thus what you would need is a notion of “a given type which kind is polymorphic variant”.

Another point that is problematic in your code is that classes are more than types. The class declaration

class x= object val x = 0 end

defines three items; a class, a class type and a type. The argument of inherit is a class not a type.

1 Like