Ocaml 使用Cmdliner时,是否有方法对记录中的参数进行分组?
假设我有以下代码Ocaml 使用Cmdliner时,是否有方法对记录中的参数进行分组?,ocaml,Ocaml,假设我有以下代码 让main a b c d e=Format.eprintf”%b%b%b%b%B@.“a b c d e 让cmd= 让我们进去 将a=Arg.(值&标志&信息[“a”]~doc:“a”)放入 将b=Arg.(值、标志和信息[“b”]~doc:“b”)放入 将c=Arg.(值、标志和信息[“c”]~doc:“c”)放入 设d=Arg.(值&标志&信息[“d”]~doc:“d”)在 将e=Arg.(值、标志和信息[“e”]~doc:“e”)放入 术语。(const main$a
让main a b c d e=Format.eprintf”%b%b%b%b%B@.“a b c d e
让cmd=
让我们进去
将a=Arg.(值&标志&信息[“a”]~doc:“a”)放入
将b=Arg.(值、标志和信息[“b”]~doc:“b”)放入
将c=Arg.(值、标志和信息[“c”]~doc:“c”)放入
设d=Arg.(值&标志&信息[“d”]~doc:“d”)在
将e=Arg.(值、标志和信息[“e”]~doc:“e”)放入
术语。(const main$a$b$c$d$e),术语。(信息“test”~版本:“1”~文档:“abcde”~退出:默认退出~man:[])
let()=Cmdliner.Term。(退出@@eval cmd)
如果我在没有选项的情况下执行我的程序,我将获得false
,如果我将它与-ade
一起使用,我将获得true-false-true
,这正是我想要的
现在,假设我在main
函数中输入了一个拼写错误,然后改为编写
(*注意c*前面的d)
让main a b d c e=Format.eprintf“%b%b%b%b”B@.“a b c d e
如果我像以前一样使用-ade
执行主程序,我将获得true-false-true
,这可能被认为是错误的
所以,我想知道的是,是否有可能在记录中收集选项,并将它们与它们的专有名称一起使用,比如下面的示例(这不起作用):
opencmdliner
类型o={a:bool Term.t;
b:布尔项t;
c:布尔项t;
d:布尔项t;
e:bool Term.t;}
(*a-e不是布尔值,而是布尔项,它给出了一个明显的错误*)
让main{a;b;c;d;e}=Format.eprintf“%b%b%b%b%B@.“a b c d e
让cmd=
将a=Arg.(值&标志&信息[“a”]~doc:“a”)放入
将b=Arg.(值、标志和信息[“b”]~doc:“b”)放入
将c=Arg.(值、标志和信息[“c”]~doc:“c”)放入
设d=Arg.(值&标志&信息[“d”]~doc:“d”)在
将e=Arg.(值、标志和信息[“e”]~doc:“e”)放入
设o=Term.const{a;b;c;d;e}in
Term.(const main$o),Term.(信息“test”~版本:“1”~文档:“abcde”~退出:默认退出~man:[])
let()=Cmdliner.Term。(退出@@eval cmd)
这在大型项目上可能很有用,并且可以减少函数的参数数量。也许有一种方法可以做到这一点,但我找到的所有例子都使用了第一种方法。我不想在github页面上打开一个问题,所以我在这里问它 如果为记录类型编写字段更新函数,则可以非常直接地完成此操作。例如,如果我们有
type arg = { a:bool; b:bool; c:bool; d:bool; e: bool }
let main {a;b;c;d;e} = Format.eprintf "%B %B %B %B %B@." a b c d e
module Update = struct
let a a r = { r with a }
let b b r = { r with b }
let c c r = { r with c }
let d d r = { r with d }
let e e r = { r with e }
end
唯一缺少的步骤是将直接提供参数的Cmdliner.Term.t
转换为更新arg类型记录的术语。一项实施将是:
let cmd =
let open Cmdliner in
(* first the starting record *)
let start = Term.const { a = false; b=false; c=false; d=false; e=false } in
let transform r (update,arg) =
Term.( const update $ arg $ r ) in
let arg =
List.fold_left transform
start
Update.[
a, Arg.(value & flag & info ["a"] ~doc:"a");
b, Arg.(value & flag & info ["b"] ~doc:"b");
c, Arg.(value & flag & info ["c"] ~doc:"c");
d, Arg.(value & flag & info ["d"] ~doc:"d");
e, Arg.(value & flag & info ["e"] ~doc:"e");
] in
Term.(const main $ arg),
Term.info "test"
~version:"1"
~doc:"abcde"
~exits:Term.default_exits
~man:[]
let () = Cmdliner.Term.(exit @@ eval cmd)
我真的很喜欢你的解决方案,但问题是它让我创造了一个与cmdliner理念背道而驰的首发记录。这就是为什么我没有找到解决问题的方法,因为我想找到一种方法,从
'a Cmdliner.Term.t
记录到'a
记录。