Class 具有接受派生类的方法的ocaml类

Class 具有接受派生类的方法的ocaml类,class,inheritance,ocaml,Class,Inheritance,Ocaml,考虑以下代码: module Proxy = struct type 'a t end class qObject proxy = object(self : 'self) method proxy : 'self Proxy.t = proxy end class qWidget proxy = object(self : 'self) inherit qObject proxy method add : qWidget -> unit = fun w -> (

考虑以下代码:

module Proxy = struct
  type 'a t
end

class qObject proxy = object(self : 'self)
  method proxy : 'self Proxy.t = proxy
end

class qWidget proxy = object(self : 'self)
  inherit qObject proxy
  method add : qWidget -> unit = fun w -> ()
  method as_qWidget = (self :> qWidget)
end

class qButton proxy = object(self : 'self)
  inherit qWidget proxy
  method text = "button"
end

let qObject_proxy : qObject Proxy.t = Obj.magic 0
let qWidget_proxy : qWidget Proxy.t = Obj.magic 0
let qButton_proxy : qButton Proxy.t = Obj.magic 0

let qObject = new qObject qObject_proxy
let qWidget = new qWidget qWidget_proxy
let qButton = new qButton qButton_proxy

let () = qWidget#add qWidget
let () = qWidget#add qButton#as_qWidget
这段代码的类型和编译都很好。但qButton必须手动转换为qWidget,我想消除它。我希望qWidget#add接受另一个qWidget或任何派生类(如qButton)。我认为#qWidget是合适的类型,但这不起作用:

class qWidget proxy = object(self : 'self)
  inherit qObject proxy
  method add : #qWidget -> unit = fun w -> ()
end

Error: Some type variables are unbound in this type: ...
The method add has type 'c -> unit where 'c is unbound


有没有什么方法是我看不到的?

我找到了一种方法。诀窍在于add不需要一个从qWidget派生的对象,而只需要一个可以将自身强制转换为qWidget的对象,就像在中使用as_qWidget方法一样。这样就可以将必要的转换为qWidget,而不需要麻烦的qWidget

class qWidget proxy=object(self:'self)
继承qObject代理
方法添加:'a。(作为'a)->单位
=fun w->让w=w作为()
方法为_qWidget=(self:>qWidget)
结束

作为qWidget工作中的侧节点
方法add_obj:#qObject->unit=fun o->()
。只是不是qWidget本身。我尝试了很多不起作用的东西。这看起来很不错。
class qWidget proxy = object(self : 'self)
  inherit qObject proxy
  method add : 'a . (#qWidget as 'a) -> unit = fun w -> ()
end

Error: The universal type variable 'a cannot be generalized:
it escapes its scope.
class qWidget proxy = object(self : 'self)
  inherit qObject proxy
  method add : 'a . (<as_qWidget : qWidget; ..> as 'a) -> unit
             = fun w -> let w = w#as_qWidget in ()
  method as_qWidget = (self :> qWidget)
end