2012-10-11 3 views
6

Sexplib의 구문 확장은 OCaml에서 임의의 사용자 정의 데이터 구조의 직렬화 및 비 직렬화를 쉽게 만듭니다. 그것은 일반적으로 유형 정의의 마지막에 with sexp 주석을 추가하면된다 :Map과 같은 functor 유형에 sexplib을 어떻게 사용할 수 있습니까?

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

이 펑 기반 유형에 직접 일반화하는 것 같지 않으며,이 Sexplib 표준 타입 컨버터도 캡처 할 수있는 방법을 명확 표준 펑터

지금까지 일련 번호 지정 전에 목록에 특정 Map 유형 인스턴스 (예 : int Map.Make(String).t)를 병합하여이 문제를 해결했지만, 분명히 일반적으로 야심적 인 Sexplib/Jane의 저자가 간과하지 않았습니다. 스트리트 코어. 또한 버전의 배터리가 [Bat] Map과 같은 주요 모듈에 맞춤식 sexp 직렬화를 통해 믹스되지만이 기능은 잠시 동안 삭제되었습니다.

지도 또는 기타 복잡한 펑터 유형은 일반적으로 Sexplib 직렬화에 사용됩니까?

+2

나는 퍼베이시브 섹스 플립 변환 함수가있는 확장 된 표준 라이브러리를 사용할 것이라고 생각합니다. '코어'를 보셨습니까? 나는 5 분만 보냈지 만,이 5 분 동안 펑터'Set.Make'를 적용했고, 결과 집합 타입에 대한 섹스 플립 변환 함수를 만들 수 있도록 인수 타입에 대한 섹스 플립 변환 함수를 요청했습니다. –

답변

1

한 가지 방법은 데이터를 serialize하는 데 필요한 추가 정보를 취하는 새로운 Functor를 정의하는 것입니다. 여기 배터리와 함께 과거에 사용한 완전한 구현이 있습니다. 참고 나는 또한 맵의 예외적이고 라벨이 붙은 버전을 선호했기 때문에 그것들을 열어 보았습니다. 물론 제거 할 수는 있습니다.

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 

정확하게 기억한다면 배터리는 추가 라이브러리에 대한 의존성을 줄이기 위해 이러한 기능을 제거했습니다. 다른 옵션은 이러한 기능을 즉시 사용할 수있는 코어를 사용하는 것입니다.