我正在尝试使用 ppxlib 编写简单的重写器,以了解如何做更复杂的事情。
我目前正在与 Metaquot 作斗争。我找到的文档是这个,但它只是触及表面,.ml 或 .mli 文件中没有任何内容可以帮助理解可能性。
我正在努力改变
let x = <expr>
进入
let x =
let res = <expr> in
res
我把两个都甩了:
[{pstr_desc =
Pstr_value (Nonrecursive,
[{pvb_pat = {ppat_desc = Ppat_var {txt = "x"}; ppat_loc_stack = []};
pvb_expr =
{pexp_desc = Pexp_constant (Pconst_integer ("23", None));
pexp_loc_stack = []}}])}]
和
[{pstr_desc =
Pstr_value (Nonrecursive,
[{pvb_pat = {ppat_desc = Ppat_var {txt = "x"}; ppat_loc_stack = []};
pvb_expr =
{pexp_desc =
Pexp_let (Nonrecursive,
[{pvb_pat =
{ppat_desc = Ppat_var {txt = "res"}; ppat_loc_stack = []};
pvb_expr =
{pexp_desc = Pexp_constant (Pconst_integer ("23", None));
pexp_loc_stack = []}}],
{pexp_desc = Pexp_ident {txt = Lident "res"}; pexp_loc_stack = []});
pexp_loc_stack = []}}])}]
所以我需要将
Pexp_constant ...
转换为 Pexp_let ...
我想出了这个:
let wrap_with_fun_call expr loc _key =
let open Ppxlib.Ast_helper in
[%expr
[%e
Exp.let_ Nonrecursive
[
( Exp.ident
@@ { txt = Parse.longident (Lexing.from_string "res"); loc },
expr );
]
(Exp.ident @@ { txt = Parse.longident (Lexing.from_string "res"); loc })]]
但是第一个
Exp.ident @@ ...
没有正确的类型,我陷入了困境。我在 ppxlib 中找不到任何生成 value_binding list
的内容,也找不到很好的在线示例或文档来解释元引用的可能性(除了我之前链接的文档)
是否有一些好的资源可以帮助您更好地了解可能性以及如何做到这一点?
肯定有一种简单的方法可以用metaquot做我想做的事情(因为它相对简单),但我找不到如何做。
所以答案很简单:
[%expr
let res = [%e expr] in
res]
让我困惑的是我没有写
in res
部分,错误信息具有误导性(eval expected
)