【问题标题】:Instantiate a module in OCaml dynamically动态实例化 OCaml 中的模块
【发布时间】:2015-05-25 13:56:43
【问题描述】:

我有几个模块实现了相同的接口。我只想根据命令行中给出的一个参数加载此模块中的一个。

我正在考虑使用一流的模块,但问题是我想在模块实例化之前执行一些功能。

目前我有这个:

module Arch = (val RetrolixAbstractArch.get_arch() : RetrolixAbstractArch.AbstractArch)


let get_arch () =
  let arch = Options.get_arch() in
  if arch = "" then
    Error.global_error "During analysis of compiler's architecture"
               "No architecture specified"
  else
    if arch = "mips" then
      ( module MipsArch : AbstractArch)
    else
    Error.global_error "During analysis of compiler's architecture"
               (Printf.sprintf "Architecture %s not supported or unknown" arch)      

但是由于命令行还没有解析,Options.get_arch给我空字符串。

我想在这个函数执行之前实现命令行解析(不添加函数中的解析)。可能吗 ?我应该找到其他方法来实现这一点吗?

【问题讨论】:

  • 什么是Options,为什么不在调用这个(整个问题的)模块的get_arch 之前调用命令行解析器?
  • 我的问题是函数get_arch在main函数之前被调用。所以此时不​​调用命令行解析器。但是调用两次会很奇怪。 options是存储程序选项变量的模块,变量依赖于命令行。
  • 为什么在main函数之前调用get_arch?它是某些模块的模块初始化的一部分吗?你能重新排列它,让你有一些其他的主函数,它可以让你控制调用的顺序,包括命令行解析器get_arch,以及你当前的主函数?

标签: command-line module ocaml first-class


【解决方案1】:

这是可能的,但您必须使用本地模块。这是一个小问题,基本上只需要很少的重构。

let arch_of_name = function
  | "mips" -> (module MipsArch : AbstractArch)
  | "arm"  -> (module Arm)
  | _ -> invalid_arg "unknown arch"


let main () = 
  ...
  let arch_name = get_arch () in
  let module Arch = (val arch_of_name arch_name) in
  (* here you can use module Arch as usual *)

另一种方法是使用拱形结构对模块进行函子化,并在您了解架构后立即实例化函子。你可以看到一个完整的例子here(参见函数target_of_arch,它为特定架构创建了一流的模块)。

如果您的AbstractArch 接口不包含类型定义,那么您可以使用其他抽象来代替模块:函数或对象的记录。它们可能会更顺利地工作,甚至可能允许您动态地重载 arch 实例(通过将 arch 实例作为参考,尽管我不建议这样做,因为它很不干净,imo)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-29
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    相关资源
    最近更新 更多