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

OCaml:自动安装自定义打印机,ocaml,Ocaml,我为一个模块实现了一个漂亮的打印机。目前,我启动了utop,加载依赖项,然后执行#安装打印机pp_自定义其中pp_custom是漂亮的打印机 我想将其自动化,这样我就可以以类似于lacaml库的方式使用它,默认情况下矩阵的漂亮打印机是“安装”的 我该怎么做呢?简而言之,每当您在顶部加载库时,都需要运行\install\u printer指令。我使用以下代码来评估顶层中的代码: open Core_kernel.Std open Or_error let eval_exn str = let

我为一个模块实现了一个漂亮的打印机。目前,我启动了
utop
,加载依赖项,然后执行
#安装打印机pp_自定义其中
pp_custom
是漂亮的打印机

我想将其自动化,这样我就可以以类似于
lacaml
库的方式使用它,默认情况下矩阵的漂亮打印机是“安装”的


我该怎么做呢?

简而言之,每当您在顶部加载库时,都需要运行
\install\u 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\u kernel
,但您可以通过使用
eval\u exn
而不是
eval
(最后一个将可能的异常封装到
或\u error
monad中)轻松地解决这个问题。一旦您拥有
eval
功能,就可以使用它加载打印机:

 let () = eval (sprintf "#install_printer %s;;" printer)
其中,
printer
是pretty printing函数的名称(通常用模块名限定)。通常,人们会将这些代码放入单独的库中,名为
library.top
,其中
library
是您的库的名称


为了进一步实现自动化,您可以要求希望在toplevel中自动打印的所有类型在中心注册表中注册自己,然后调用所有已注册的打印机,而不是手动枚举它们。要同时看到所有这些都起作用,您可以查看。它有一个名为
bap.top
的子库,可以自动安装所有打印机。希望可打印的每种类型都使用functor实现
printable
签名,它不仅从基本定义派生出许多打印函数,而且还将生成的漂亮打印机注册到Core_内核的
pretty_printer
注册表中(您可以使用自己的注册表,这只是一组字符串,仅此而已)。将
bap.top
库加载到顶级时(使用
require
load
指令),它将枚举所有已注册的打印机和它们。

简而言之,每当您在顶部加载库时,您需要运行
\install\u 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\u kernel
,但您可以通过使用
eval\u exn
而不是
eval
(最后一个选项将一个可能的异常包装到
或\u error
monad中)轻松解决此问题。一旦您获得了
eval
功能,就可以使用它加载打印机:

 let () = eval (sprintf "#install_printer %s;;" printer)
其中,
printer
是pretty printing函数的名称(通常用模块名限定)。通常,将此类代码放入名为
library的单独库中。top
,其中,
library
是库的名称


为了实现进一步的自动化,您可以要求希望在toplevel中自动打印的所有类型在中央注册表中注册,然后调用所有已注册的打印机,而不是手动枚举它们。要查看所有这些工作,您可以查看。它有一个名为
bap.top
的子库,可以自动安装所有打印机。需要打印的每种类型都使用functor实现
printable
签名,它不仅从基本定义派生许多打印函数,而且还将生成的漂亮打印机注册到Core\u内核的
pretty\u printer
注册表中(您可以使用自己的注册表,这只是一组字符串,仅此而已)。将
bap.top
库加载到顶级时(使用
require
load
指令),它枚举了所有注册的打印机和它们。

所以我刚刚尝试用
corebuild
运行这段代码,我得到了
Toploop
的一个未绑定模块错误。是否还有一些其他命令需要传递到
corebuild
以包含
Toploop
?我还很好奇为什么我可以访问
Toploop.execute_短语
来自
utop
,即使它没有出现在底部的列表中。对不起,忘了提到主要部分,这个
Toploop
来自
compiler libs
包,它是在QPL许可下随OCaml一起提供的。您需要将
-pkg compiler libs
传递到
corebuild
到访问它。很抱歉一再打扰您,但我现在得到的是
错误:没有为以下模块提供实现:从io.cmx引用的Toploop
findlib
声称
接口topdirs.cmi出现在多个目录中:/root/.opam/4.01.0/lib/ocaml/compiler-libs,/root/.opam/4.01.0/lib/ocaml
。我不确定错误和警告是否有某种关联。我已经检查了
/root.opam/4.0.1.0/lib/ocaml/compiler libs
,我确实在其中看到了
toploop.cmi
。不要为这个警告而烦恼,它是已知的问题,应该不会影响结果。关于
没有实现的问题呢m、 在编译库时,您应该向
corebuild
提供
-pkg编译器libs
,比如:
corebuild-pkg编译器libs yourlibrary.cma
,所以我刚刚试着用
corebuild
运行了这段代码,我得到了
Toploop
的未绑定模块错误。还有其他命令需要吗o传递到
corebuild
以使其包含
Toploop
?我也很好奇为什么我可以访问
Toploop。从
utop
执行短语
,即使它没有出现在底部的列表中。对不起,忘了提到主要部分,这个
Toploop
来自
编译器libs
paOCaml附带的QPL许可证下的打包。您需要将
-pkg编译器libs
传递到
corebuild
才能访问