pretty printer
今まで,デバッグprintf用にExtLibのStd.printを使ってきたが,フィールド名の情報がなくなってタグ番号の様な数字に化けてしまう。複雑なデータ構造になると直感的に理解できないので,ちょっと不便だなあと思っていたところに,d:id:KeisukeNakano:20081011を見つけた。
「使い方」の部分を見て,見よう見まねでjson-wheelのJson_typeのprety-printerを作ってみた。
(* PP for Json_type *) let rec pp_json fmt = let pp_tuple_string_json = pp_tuple (fun (s, j) -> [pp_poly pp_string s; pp_poly pp_json j]) in let pp_dict_item_list = pp_list pp_tuple_string_json in let pp_json_list = pp_list pp_json in pp_variant (function | Json_type.Object o -> "Object", [pp_poly pp_dict_item_list o] | Json_type.Array a -> "Array", [pp_poly pp_json_list a] | Json_type.String s -> "String", [pp_poly pp_string s] | Json_type.Int i -> "Int", [pp_poly pp_int i] | Json_type.Float f -> "Float", [pp_poly pp_float f] | Json_type.Bool b -> "Bool", [pp_poly pp_bool b] | Json_type.Null -> "Null", []) fmt
実行例:
# let j = Json_io.json_of_string("{\"a\": [1,2.0,\"3\"]}");; val j : Json_type.t = Object [("a", Array [Int 1; Float 2.; String "3"])] # open ExtLib;; # Std.print j;; ([("a", Tag1 ([Tag3 (1); Tag4 (2.); Tag2 ("3")]))]) - : unit = () # Format.printf "%a@." pp_json j;; Object([("a", Array([Int(1); Float(2.); String("3")]))]) - : unit = ()
参照型の場合は,こんな感じでいいのかな?
let pp_ref pp_a = pp_record (fun x -> ["contents", pp_poly pp_a x.contents]) let pp_bool_ref = pp_ref pp_bool let pp_int_ref = pp_ref pp_int let pp_float_ref = pp_ref pp_float let pp_char_ref = pp_ref pp_char let pp_string_ref = pp_ref pp_string
実行例:
# let a = ref 10;; val a : int ref = {contents = 10} # Format.printf "%a@." pp_int_ref a;; {contents = 10} - : unit = ()