Module 选择要与命令行参数一起使用的ocaml模块

Module 选择要与命令行参数一起使用的ocaml模块,module,functional-programming,ocaml,Module,Functional Programming,Ocaml,在我的代码中,我使用了模块M=Implementation1,然后我引用了M,而不是Implementation1。问题是,我必须重新编译我的程序以将Implementation1更改为Implementation2。我想通过命令行参数控制要从哪个实现使用。可能吗 当所有实现共享签名时,情况是否更简单 对于大多数版本的OCaml,您可以使用camlp4执行此操作 IFDEF USE_IMP1 THEN module M = Implementation1 ELSE module M =

在我的代码中,我使用了
模块M=Implementation1
,然后我引用了
M
,而不是
Implementation1
。问题是,我必须重新编译我的程序以将
Implementation1
更改为
Implementation2
。我想通过命令行参数控制要从哪个实现使用。可能吗


当所有实现共享签名时,情况是否更简单

对于大多数版本的OCaml,您可以使用camlp4执行此操作

IFDEF USE_IMP1 THEN
  module M = Implementation1
ELSE
  module M = Implementation2
END
然后通过如下预处理选项,将选择正确的选项合并到构建中

-pp "camlp4of -UUSE_IMP1" //to undefine USE_IMP1
-pp "camlp4of -DUSE_IMP1" //to define USE_IMP2
对于OCaml>=4.00.0的版本,您可以使用第一类模块和如下表达式:

module Choose = (val (if use_impl1 then (module Impl_1) else (module Impl_2)) : IMP)

要使用if语句选择由
值确定的模块,请使用\u impl1
值。

因为这两种实现都是静态已知的,所以可以使用。关于如何构造程序,有很多不同的可能性,下面是一种最小化顶级引用单元格和顶级有效语句的可能性:

module type M = sig
  val test : unit -> unit
end

module M1 : M = struct
  let test () = Printf.printf "Implementation 1\n%!" 
end

module M2 : M = struct
  let test () = Printf.printf "Implementation 2\n%!"
end

let test m = 
  let module M = (val m : M) in 
  (* If other modules of your program depend on the implementation of 
     M, functorize them over sig M and instantiate them with M here. *)
  M.test ()

let main () = 
  let exec = Filename.basename Sys.executable_name in 
  let usage = Printf.sprintf
      "Usage: %s [OPTION]...\n\
       Program synopsis.\n\
       Options:" exec 
  in
  let m = ref (module M1 : M) in
  let options = [
    "-m1", Arg.Unit (fun () -> m := (module M1 : M)), 
    " Use implementation 1 (default)"; 
    "-m2", Arg.Unit (fun () -> m := (module M2 : M)),
    " Use implementation 2"; ]
  in
  let anon _ = raise (Arg.Bad "no positional argument supported") in 
  Arg.parse (Arg.align options) anon usage; 
  test !m

let () = main ()

你的问题不够清楚。您是只处理静态已知的两个实现,在这种情况下您应该查找,还是处理稍后可能添加的实现,在这种情况下您需要查找。我有两个静态已知的实现。