2012-10-11 18 views
6

Sexplib'in sözdizimi uzantısı, isteğe bağlı olarak kullanıcı tanımlı veri yapılarının seri hale getirilmesini ve seri hale getirilmesini OCaml'de kolaylaştırır. Genellikle bir tip tanımı sonuna bir with sexp ek açıklaması ekleyerek yapılır:Sexplib, Harita gibi functor türleriyle nasıl kullanılabilir?

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

Bu funktor tabanlı türlerine doğrudan genelleme görünmüyor, ne de Sexplib standart tip dönüştürücüler bile yakalayabilir nasıl açıktır standart çekiciler.

Şimdiye kadar, belirli bir Harita türü örneğini (örn. int Map.Make(String).t) serileştirmeden önce bir listeyle düzleştirerek çalıştım ve bunun tersi de doğrudur, ama kesinlikle Sexplib/Jane'in genellikle iddialı yazarları tarafından göz ardı edilmemiştir. Sokak Çekirdeği. Ayrıca Piller'in eski sürümlerinin özel sexp serileştirme işleminde [Bat] Map gibi ana modüllerine karıştığını, ancak bunun bir süredir kaldırıldığını fark ettim.

Haritalar veya diğer karmaşık functor türleri, Sexplib serileştirme işleminde yaygın olarak nasıl kullanılır?

+2

Bunun için genişletilmiş bir standart kitaplık ile yaygın bir adet cinsiyete dönüştürme işlevi kullanacağınızı düşünüyorum. Çekirdek'e baktın mı? Ben sadece 5 dakika harcadım ama bu 5 dakika içinde funk set.make 'yi kullandım ve sonuçta set türü için sexplib dönüşüm fonksiyonlarını oluşturabilmem için argüman türünde sexplib dönüşüm fonksiyonlarını sordum. –

cevap

1

Verileri serileştirmek için gereken ek bilgileri alan yeni bir functor tanımlamaktır. İşte geçmişte Piller ile kullandığım tam bir uygulama. Not Ayrıca, Haritanın istisnasız ve etiketli sürümünü tercih ettim, bu yüzden bunları açtım, ama elbette bunu kaldırabilirsiniz.

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 

Doğru hatırlamak

, Piller ek kütüphaneler üzerinde bağımlılıkları azaltmak için bu tür özellikler kaldırıldı. Diğer seçeneğiniz, bu işlevleri kullanıma hazır olan Core'u kullanmaktır.

İlgili konular