我试图通过ppx派生在OCaml中漂亮地打印包含哈希表(使用基础标准库)的自定义记录类型,但我需要实现Hashtbl.pp才能使其工作。
我尝试在网上查看示例,我找到的最好的示例是https://github.com/ocaml-ppx/ppx_deriving#testing-plugins,但我仍然收到奇怪的类型错误,如“此函数的类型为Formatter.t -> (string,Value.t) Base.Hashtbl.t -> unit.它应用于太多参数;可能您忘记了一个`;'”
如何使用pp函数扩展Hashtbl模块?
到目前为止,我的代码如下(Value.t是一个自定义类型,我用@@deriving show成功地对其进行了注释
open Base
(* Extend Hashtbl with a custom pretty-printer *)
module Hashtbl = struct
include Hashtbl
let rec (pp : Formatter.t -> (string, Value.t) Hashtbl.t -> Ppx_deriving_runtime.unit) =
fun fmt -> function
| ht ->
List.iter
~f:(fun (str, value) ->
Caml.Format.fprintf fmt "@[<1>%s: %s@]@." str (Value.string_of value))
(Hashtbl.to_alist ht)
and show : (string, Value.t) Hashtbl.t -> Ppx_deriving_runtime.string =
fun s -> Caml.Format.asprintf "%a" pp s
;;
end
type t =
{ values : (string, Value.t) Hashtbl.t
; enclosing : t option
}
[@@deriving show]发布于 2020-01-15 03:20:13
解决方案1
您的记录的values字段的类型是具有两个类型变量的参数化的,因此派生器尝试使用由键和数据打印机参数化的通用pp函数,例如,下面将为任何哈希表启用show (具有任何键和任何值,只要键和值是可显示的,
module Hashtbl = struct
include Base.Hashtbl
let pp pp_key pp_value ppf values =
Hashtbl.iteri values ~f:(fun ~key ~data ->
Format.fprintf ppf "@[<1>%a: %a@]@." pp_key key pp_value data)
end所以你终于可以定义你的类型了
type t = {
values : (string,Value.t) Hashtbl.t;
enclosing : t option;
} [@@deriving show]解决方案2(推荐)
然而,我建议另一种方法,不是创建一个通用的哈希表模块,而是创建一个专门的Values模块,例如,
module Values = struct
type t = (string, Value.t) Hashtbl.t
let pp ppf values =
Hashtbl.iteri values ~f:(fun ~key ~data ->
Format.fprintf ppf "@[<1>%s: %s@]@." key (Value.to_string data))
end现在您可以使用它作为,
type t = {
values : Values.t;
enclosing : t option;
} [@@deriving show]解决方案3
如果您仍然需要一个通用的可打印哈希表,那么我建议您不要使用include语句,而是只为('k,'s) Hashtbl.t类型实现所需的可打印接口,例如,
module Hashtbl_printable = struct
type ('k,'s) t = ('k, 's) Hashtbl.t
let pp pp_key pp_value ppf values =
Hashtbl.iteri values ~f:(fun ~key ~data ->
Format.fprintf ppf "@[<1>%a: %a@]@." pp_key key pp_value data)
end
type t = {
values : (string, Value.t) Hashtbl_printable.t;
enclosing : t option;
} [@@deriving show]https://stackoverflow.com/questions/59740132
复制相似问题