我为模块实现了一台漂亮的打印机。目前我启动utop
,加载依赖项然后执行#install_printer pp_custom;;
,其中pp_custom
是漂亮的打印机。
我想自动执行此操作,以便我能够以类似于lacaml
库的方式使用它,其中矩阵的漂亮打印机已安装"默认情况下。
我将如何做到这一点?
答案 0 :(得分:4)
简而言之,只要在顶部加载库,就需要运行#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)
这取决于Core_kernel
,但您只需使用eval_exn
代替eval
即可轻松摆脱此问题(最后一个将可能的异常包含在Or_error
中} monad)。获得eval
功能后,可以使用它来加载打印机:
let () = eval (sprintf "#install_printer %s;;" printer)
其中printer
是漂亮打印功能的名称(通常用模块名称限定)。通常,会将此类代码放入名为library.top
的单独库中,其中library
是您的库的名称。
为了进一步实现自动化,您可以要求所有要在顶层自动打印的类型,在中央注册表中注册自己,然后调用所有已注册的打印机,而不是手动枚举它们。要立即查看所有这些内容,您可以查看BAP library。它有一个名为bap.top
的子库,可自动安装所有打印机。希望可打印的每种类型使用Printable.Make
仿函数实现Printable
签名,不仅从基本定义中派生出许多打印函数,还在Core_kernel中注册生成的漂亮打印机Pretty_printer
注册表(您可以使用自己的注册表,这只是一组字符串,仅此而已)。将bap.top
库加载到顶层(使用require
或load
指令)时,它会枚举所有已注册的打印机并install。