Title here
Summary here
Our program demonstrates JSON encoding and decoding in OCaml, including handling of basic data types and custom data structures.
open Yojson.Basic.Util
(* We'll use these two record types to demonstrate encoding and
decoding of custom types below. *)
type response1 = {
page: int;
fruits: string list;
}
(* In OCaml, all record fields are exported by default. *)
type response2 = {
page: int;
fruits: string list;
}
let () =
(* First we'll look at encoding basic data types to
JSON strings. Here are some examples for atomic values. *)
let bool_json = `Bool true |> Yojson.Basic.to_string in
print_endline bool_json;
let int_json = `Int 1 |> Yojson.Basic.to_string in
print_endline int_json;
let float_json = `Float 2.34 |> Yojson.Basic.to_string in
print_endline float_json;
let string_json = `String "gopher" |> Yojson.Basic.to_string in
print_endline string_json;
(* And here are some for lists and associative lists, which encode
to JSON arrays and objects as you'd expect. *)
let list_json = `List [`String "apple"; `String "peach"; `String "pear"] |> Yojson.Basic.to_string in
print_endline list_json;
let assoc_json = `Assoc [("apple", `Int 5); ("lettuce", `Int 7)] |> Yojson.Basic.to_string in
print_endline assoc_json;
(* The Yojson library can automatically encode your
custom data types. *)
let res1 = {
page = 1;
fruits = ["apple"; "peach"; "pear"];
} in
let res1_json = `Assoc [
("page", `Int res1.page);
("fruits", `List (List.map (fun s -> `String s) res1.fruits))
] |> Yojson.Basic.to_string in
print_endline res1_json;
(* The encoding is the same for response2 since all fields are exported by default in OCaml *)
let res2 = {
page = 1;
fruits = ["apple"; "peach"; "pear"];
} in
let res2_json = `Assoc [
("page", `Int res2.page);
("fruits", `List (List.map (fun s -> `String s) res2.fruits))
] |> Yojson.Basic.to_string in
print_endline res2_json;
(* Now let's look at decoding JSON data into OCaml values.
Here's an example for a generic data structure. *)
let json_str = {|{"num":6.13,"strs":["a","b"]}|} in
let json = Yojson.Basic.from_string json_str in
(* We can access the values in the decoded JSON using utility functions. *)
let num = json |> member "num" |> to_float in
Printf.printf "%.2f\n" num;
(* Accessing nested data requires a series of operations. *)
let strs = json |> member "strs" |> to_list |> filter_string in
let str1 = List.hd strs in
print_endline str1;
(* We can also decode JSON into custom data types. *)
let json_str = {|{"page": 1, "fruits": ["apple", "peach"]}|} in
let json = Yojson.Basic.from_string json_str in
let res = {
page = json |> member "page" |> to_int;
fruits = json |> member "fruits" |> to_list |> filter_string;
} in
Printf.printf "page: %d, first fruit: %s\n" res.page (List.hd res.fruits);
(* In OCaml, we typically write to channels like stdout directly. *)
let oc = stdout in
let json = `Assoc [("apple", `Int 5); ("lettuce", `Int 7)] in
Yojson.Basic.to_channel oc json;
print_newline ()
To run this program, you’ll need to install the yojson
library using OPAM:
$ opam install yojson
Then compile and run the program:
$ ocamlc -o json_example json_example.ml -package yojson
$ ./json_example
This will output:
true
1
2.34
"gopher"
["apple","peach","pear"]
{"apple":5,"lettuce":7}
{"page":1,"fruits":["apple","peach","pear"]}
{"page":1,"fruits":["apple","peach","pear"]}
6.13
a
page: 1, first fruit: apple
{"apple":5,"lettuce":7}
We’ve covered the basics of JSON in OCaml here, but check out the Yojson documentation for more detailed information on working with JSON in OCaml.