OCaml:自动安装自定义漂亮打印机

ayc*_*ycc 1 ocaml

我已经为一个模块实现了一个漂亮的打印机。目前我启动utop,加载依赖项然后做漂亮的打印机#install_printer pp_custom;;在哪里pp_custom

我想自动执行此操作,以便我可以以类似于lacaml默认情况下“安装”矩阵的漂亮打印机的库的方式拥有它。

我该怎么做呢?

ivg*_*ivg 5

简而言之,#install_printer每当您在顶部加载库时,您都需要运行指令。我正在使用以下代码来评估顶层中的代码:

open Core_kernel.Std
open Or_error

let eval_exn str =
  let lexbuf = Lexing.from_string str in
  let phrase = !Toploop.parse_toplevel_phrase lexbuf in
  Toploop.execute_phrase false Format.err_formatter phrase

let eval str = try_with (fun () -> eval_exn str)
Run Code Online (Sandbox Code Playgroud)

这取决于Core_kernel,但您可以轻松摆脱这一点,只需使用eval_exn代替eval(最后一个将可能的异常包装到Or_errormonad 中)。一旦你有了这个eval功能,它就可以用来加载你的打印机:

 let () = eval (sprintf "#install_printer %s;;" printer)
Run Code Online (Sandbox Code Playgroud)

哪里printer是漂亮打印函数的名称(通常用模块名称限定)。通常,将此类代码放入单独的库中,命名为library.top,其中library是您的库的名称。

为了进一步自动化,您可以要求所有类型,您希望在顶层自动打印,在中央注册表中注册自己,然后调用所有注册的打印机,而不是手动枚举它们。要立即查看所有这些工作,您可以查看BAP 库。它有一个称为bap.top自动安装所有打印机的子库。每种希望可打印的类型都Printable使用Printable.Make函子实现签名,它不仅从基本定义中派生出许多打印功能,而且还将生成的漂亮打印机注册到 Core_kernel 的Pretty_printer注册表中(您可以使用自己的注册表,这只是一个集合字符串,仅此而已)。当bap.top库加载到顶层时(使用requireload指令),它枚举所有注册的打印机并安装它们。