首页 > 解决方案 > OCaml - 如何将 Yaml 序列化和反序列化为记录

问题描述

当前社区首选的用于解析和使用 YAML 的库是什么,以及如何使用它们来序列化和反序列化这样的记录:

type book = { 
  title: string;
  authors: string list
}

标签: yamlocaml

解决方案


这就是我得到字符串 - >记录并返回的方式。

$ opam update 
$ opam install yaml ppx_deriving_yaml

preprocess使用以下子句更新沙丘:

; `dune` file
(executable
 (name main)
 (libraries yaml)
 (preprocess
  (pps ppx_deriving_yaml)))

精简版:

let serialize_book (book_rec : book) : (string, string) result =
  let res = Yaml.to_string (book_to_yaml book_rec) in
  map_error ~f:(fun (`Msg m) -> m) res

let deserialize_book (book_str : string) : (book, string) result =
  let res =
    Yaml.of_string book_str >>= fun yaml_value -> book_of_yaml yaml_value
  in
  map_error ~f:(fun (`Msg m) -> m) res

更详细/描述性的版本:

(* Define a record *)
(* `[@@deriving yaml]` generates a bunch of functions, one being `book_to_yaml` to convert the record into a Yaml type, another `book_of_yaml` to convert Yaml type to record *)
type book = { 
  title: string;
  authors: string list
} [@@deriving yaml]

let serialize =
  let (v: book) = { title = "Cryptonomicon"; authors = [ "Neal Stephenson" ] } in 
  (* `book_to_yaml` converts from record to `yaml res` where res is a Result *)
  let yaml_structure = book_to_yaml v in 
  (* `to_string` converts from a `yaml` type'ed data structure to string *)
  match Yaml.to_string yaml_structure with 
  | Ok s ->
    print_endline ("Serialize:");
    print_endline (s)
  | Error (`Msg e) -> print_endline e

let deserialize = 
  let str = "title: Cryptonomicon\nauthors:\n- Neal Stephenson" in
  (* `of_string converts from string to a `yaml res` data structure, where `res` is Result *)
  match Yaml.of_string str with 
  | Ok yaml_value ->
    (* `book_of_yaml` is generated by `[@@deriving yaml]` *)
    (* `book_of_yaml` converts from `yaml` type to `book res` where res is Result  *)
    (match book_of_yaml yaml_value with
    | Ok t -> 
      print_endline ("Deserialize:");
      print_endline ("Title: " ^ t.title); 
      print_endline ("Authors: " ^ String.concat ", " t.authors);
    | Error `Msg e -> print_endline ("Error - convert to book: " ^ e))
  | Error `Msg e -> print_endline ("Error - parsing: " ^ e)  

推荐阅读