首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在OCaml中漂亮地打印Hashtbl以使用ppx派生

在OCaml中漂亮地打印Hashtbl以使用ppx派生
EN

Stack Overflow用户
提问于 2020-01-15 03:00:32
回答 1查看 354关注 0票数 3

我试图通过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成功地对其进行了注释

代码语言:javascript
复制
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]
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-15 03:20:13

解决方案1

您的记录的values字段的类型是具有两个类型变量的参数化的,因此派生器尝试使用由键和数据打印机参数化的通用pp函数,例如,下面将为任何哈希表启用show (具有任何键和任何值,只要键和值是可显示的,

代码语言:javascript
复制
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

所以你终于可以定义你的类型了

代码语言:javascript
复制
type t = {
  values : (string,Value.t) Hashtbl.t;
  enclosing : t option;
} [@@deriving show]

解决方案2(推荐)

然而,我建议另一种方法,不是创建一个通用的哈希表模块,而是创建一个专门的Values模块,例如,

代码语言:javascript
复制
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

现在您可以使用它作为,

代码语言:javascript
复制
type t = {
  values : Values.t;
  enclosing : t option;
} [@@deriving show]

解决方案3

如果您仍然需要一个通用的可打印哈希表,那么我建议您不要使用include语句,而是只为('k,'s) Hashtbl.t类型实现所需的可打印接口,例如,

代码语言:javascript
复制
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]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59740132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档