command-line - 动态实例化 OCaml 中的模块

标签 command-line module ocaml first-class

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

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

目前我有这个:

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给我空字符串。

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

最佳答案

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

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 接口(interface)不包含类型定义,那么您可以使用其他抽象来代替模块:函数或对象的记录。它们可能工作得更顺畅,甚至可能允许您动态重载 arch 实例(通过将 arch 实例作为引用,尽管我不建议这样做,因为它很不干净,imo )。

关于command-line - 动态实例化 OCaml 中的模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30440050/

相关文章:

bash - 你如何将 ls 的输出发送到 mv?

Python 看不到我的子包

module - 在 Racket 中找到模块的名称?

android - Android 两个模块之间的通信

ocaml - 在本地 Opam 环境中安装 Z3 OCaml 绑定(bind)时出现链接器错误

dictionary - OCaml 自引用图

OCaml:测量顶层的执行时间

unix - 如何在不登录主机的情况下从IP查找主机名

c - 尝试读取文件时出现段错误 (C)

c++ - 运行外部 .exe 并从中接收返回值