2012-10-11 25 views
6

Phần mở rộng cú pháp của Sexplib giúp việc tuần tự hóa và deserialization các cấu trúc dữ liệu do người dùng tự định nghĩa dễ dàng trong OCaml. Nó thường được thực hiện bằng cách thêm một chú thích with sexp đến cuối của một định nghĩa kiểu:Làm thế nào sexplib có thể được sử dụng với các loại functor như Map?

type a = A of int | B of float with sexp 

này dường như không để khái quát trực tiếp với các loại functor có trụ sở, cũng không phải là rõ ràng như thế nào Sexplib loại tiêu chuẩn chuyển đổi có thể chụp thậm chí các functors tiêu chuẩn. Cho đến nay tôi đã làm việc này bằng cách làm phẳng một thể loại Map cụ thể (ví dụ: int Map.Make(String).t) vào một danh sách trước khi tuần tự hóa, và ngược lại, nhưng chắc chắn điều này chưa bị bỏ qua hoàn toàn bởi các tác giả tham vọng chung của Sexplib/Jane. Lõi đường phố. Tôi cũng nhận thấy rằng phiên bản cũ hơn của Pin kết hợp theo chuỗi serialp tùy chỉnh cho các mô-đun chính của chúng như Bản đồ [Bat], nhưng điều này đã bị xóa một thời gian.

Bản đồ hoặc các loại functor phức tạp khác thường được sử dụng với serialization Sexplib như thế nào?

+2

Tôi nghĩ bạn sẽ sử dụng thư viện chuẩn mở rộng với các chức năng chuyển đổi giới tính phổ biến cho điều đó. Bạn đã xem 'Core' chưa? Tôi chỉ dành 5 phút với nó nhưng trong 5 phút này, tôi đã áp dụng hàm functor 'Set.Make' và nó yêu cầu tôi cho các hàm chuyển đổi sexplib trên kiểu đối số để nó có thể xây dựng các hàm chuyển đổi sexplib cho kiểu tập kết quả. –

Trả lời

1

Một cách là định nghĩa một hàm functor mới có thông tin bổ sung cần thiết để tuần tự hóa dữ liệu. Đây là một triển khai hoàn chỉnh mà tôi đã sử dụng trong quá khứ với Pin. Lưu ý tôi cũng ưa thích phiên bản Bản đồ không có nhãn và không có nhãn, vì vậy tôi đã mở phiên bản đó, nhưng bạn có thể loại bỏ điều đó.

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 

Nếu tôi nhớ chính xác, Pin loại bỏ các tính năng như để giảm phụ thuộc vào thư viện bổ sung. Lựa chọn khác của bạn là sử dụng Core, trong đó có các chức năng này out-of-the-box.