首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sexplib如何与像Map这样的函子类型一起使用?

sexplib如何与像Map这样的函子类型一起使用?
EN

Stack Overflow用户
提问于 2012-10-11 23:10:31
回答 1查看 622关注 0票数 6

Sexplib的语法扩展使任意用户定义的数据结构在OCaml中易于序列化和反序列化。这通常是通过在类型定义的末尾添加一个with sexp注释来完成的:

代码语言:javascript
复制
type a = A of int | B of float with sexp

这似乎并不能直接推广到基于函子的类型,也不清楚Sexplib标准类型转换器如何能够捕获甚至标准函子。

到目前为止,我已经通过在序列化之前将特定的Map类型实例(例如int Map.Make(String).t)扁平化为一个列表来解决这个问题,反之亦然,但是毫无疑问,Sexplib/Jane Street的那些雄心勃勃的作者并没有完全忽视这一点。我还注意到,旧版本的电池混合在自定义的sexp串行化到他们的主要模块如BatMap,但这已经被删除了一段时间。

如何将映射或其他复杂函子类型与Sexplib序列化一起使用?

EN

回答 1

Stack Overflow用户

发布于 2012-10-12 15:31:17

一种方法是定义一个新的函子,它接收序列化数据所需的附加信息。这是一个完整的实现,我在过去使用过电池。注意,我也更喜欢地图的无异常和标签版本,所以我已经打开了它们,但是您当然可以删除它。

代码语言:javascript
复制
module type SEXPABLE = sig
  type t
  val sexp_of_t : t -> Sexplib.Sexp.t
  val t_of_sexp : Sexplib.Sexp.t -> t
end

module Map = struct

  module type S = sig
    include BatMap.S
    include module type of Labels
    include module type of Exceptionless
    val sexp_of_t : ('a -> Sexplib.Sexp.t) -> 'a t -> Sexplib.Sexp.t
    val t_of_sexp : (Sexplib.Sexp.t -> 'a) -> Sexplib.Sexp.t -> 'a t
  end

  module Make (Ord : BatInterfaces.OrderedType)
              (Sexpable : SEXPABLE with type t = Ord.t)
              : S with type key = Ord.t = struct
    include BatMap.Make(Ord)
    include Labels
    include Exceptionless

    open Sexplib.Sexp
    open Sexplib.Conv

    let sexp_of_t sexp_of_data t =
      let f ~key ~data ans = List [Sexpable.sexp_of_t key; sexp_of_data data] :: ans in
      List (fold ~f ~init:[] t)

    let t_of_sexp data_of_sexp sexp = match sexp with
      | Atom _ -> of_sexp_error "Map.Make(...).t_of_sexp: list needed" sexp
      | List l ->
          let f ans = function
            | List [key_sexp; data_sexp] ->
                let key = Sexpable.t_of_sexp key_sexp in
                let data = data_of_sexp data_sexp in
                add ~key ~data ans
            | List _ | Atom _ ->
                of_sexp_error "Map.Make(...).t_of_sexp: 2-tuple list needed" sexp
          in
          List.fold_left ~f ~init:empty l
  end
end

如果我没记错的话,电池删除了这些功能,以减少对其他库的依赖。您的另一个选择是使用Core,它具有这些现成的功能。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12849968

复制
相关文章

相似问题

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