我可以从运行时选择的 OCaml class 继承吗?
Can I inherit from an OCaml class chosen at runtime?
所以现在我有两个相同 class 类型的 classes,例如
class foo : foo_type = object ... end
class bar : foo_type = object ... end
我想要第三个 class 在运行时继承自 foo
或 bar
。例如。 (伪语法)
class baz (some_parent_class : foo_type) = object
inherit some_parent_class
...
end
这在 OCaml 中可行吗?
用例:我正在使用对象来构造 AST 访问者,我希望能够根据一组运行时标准组合这些访问者,以便它们只对 AST 进行一次组合遍历。
编辑:我想我找到了一种使用第一个class模块创建所需class的方法:
class type visitor_type = object end
module type VMod = sig
class visitor : visitor_type
end
let mk_visitor m =
let module M = (val m : VMod) in
(module struct
class visitor = object
inherit M.visitor
end
end : VMod)
但是,为了使 "first-class" 必须将 class 包装在模块中似乎有点迂回。如果有更直接的方法请告诉我。
OCaml 有一个静态类型系统。你不能在运行时做任何会影响某物类型的事情。继承会影响事物的类型,所以它不可能在运行时发生。
(您的代码也混淆了类型和值,这是可以理解的。)
可能有一种方法可以接近您想要的,同时保留静态类型的理想属性。您实际需要的可能更像是函数组合,也许。
与 Jeffrey 所说的并不相反,但您可以使用 first-class 模块来实现。另外,我不确定您是否真的需要在运行时创建 classes,也许创建对象就足够了。如果你想要得到的是不同的行为,那么这就足够了。
这只是您已经建议的更清晰的实现,但我会这样做:
module type Foo = sig
class c : object
method x : int
end
end
module A = struct
class c = object method x = 4 end
end
module B = struct
class c = object method x = 5 end
end
let condition = true
module M = (val if condition then (module A) else (module B) : Foo)
class d = object (self)
inherit M.c
method y = self#x + 2
end
所以现在我有两个相同 class 类型的 classes,例如
class foo : foo_type = object ... end
class bar : foo_type = object ... end
我想要第三个 class 在运行时继承自 foo
或 bar
。例如。 (伪语法)
class baz (some_parent_class : foo_type) = object
inherit some_parent_class
...
end
这在 OCaml 中可行吗?
用例:我正在使用对象来构造 AST 访问者,我希望能够根据一组运行时标准组合这些访问者,以便它们只对 AST 进行一次组合遍历。
编辑:我想我找到了一种使用第一个class模块创建所需class的方法:
class type visitor_type = object end
module type VMod = sig
class visitor : visitor_type
end
let mk_visitor m =
let module M = (val m : VMod) in
(module struct
class visitor = object
inherit M.visitor
end
end : VMod)
但是,为了使 "first-class" 必须将 class 包装在模块中似乎有点迂回。如果有更直接的方法请告诉我。
OCaml 有一个静态类型系统。你不能在运行时做任何会影响某物类型的事情。继承会影响事物的类型,所以它不可能在运行时发生。
(您的代码也混淆了类型和值,这是可以理解的。)
可能有一种方法可以接近您想要的,同时保留静态类型的理想属性。您实际需要的可能更像是函数组合,也许。
与 Jeffrey 所说的并不相反,但您可以使用 first-class 模块来实现。另外,我不确定您是否真的需要在运行时创建 classes,也许创建对象就足够了。如果你想要得到的是不同的行为,那么这就足够了。
这只是您已经建议的更清晰的实现,但我会这样做:
module type Foo = sig
class c : object
method x : int
end
end
module A = struct
class c = object method x = 4 end
end
module B = struct
class c = object method x = 5 end
end
let condition = true
module M = (val if condition then (module A) else (module B) : Foo)
class d = object (self)
inherit M.c
method y = self#x + 2
end