如何用OCaml为递归嵌套的selectionSet与selections定义类型?
Got it, let's work through how to model this recursive JSON structure as OCaml records—since selectionSet and selections depend on each other, we need to use OCaml's recursive type system to handle that. Here's a step-by-step solution:
First, let's map each part of your JSON to OCaml types. We'll start with the basic Name structure, then use OCaml's type rec ... and ... syntax to define the mutually recursive selection_set and selection types. Note that we use type_ instead of type for the field name because type is a reserved keyword in OCaml.
(* Basic type for the "name" field in your JSON *) type name = { kind : string; value : string; } (* Mutually recursive types for selectionSet and selections *) type rec selection_set = { type_ : int; selections : selection list; } and selection = { name : name; selection_set : selection_set option; (* Handles null values from JSON *) }
The selection_set option type is perfect here because your JSON can have selectionSet: null—in OCaml, this maps to None, while a valid selectionSet maps to Some <selection_set_value>.
To convert your JSON string to these OCaml records, we'll use the yojson library (a common choice for JSON handling in OCaml). First, make sure you have it installed via opam: opam install yojson.
Here are the recursive parsing functions to map JSON values to our types:
open Yojson.Basic.Util let parse_name json = { kind = json |> member "kind" |> to_string; value = json |> member "value" |> to_string; } let rec parse_selection_set json = { type_ = json |> member "type" |> to_int; selections = json |> member "selections" |> to_list |> List.map parse_selection; } and parse_selection json = { name = json |> member "name" |> parse_name; selection_set = match json |> member "selectionSet" with | `Null -> None | js -> Some (parse_selection_set js) }
Let's use your sample JSON to verify the setup works:
let your_json_string = {| { "selectionSet": { "type": 1, "selections": [ { "name": { "kind": "Name", "value": "viewer" }, "selectionSet": { "type": 1, "selections": [ { "name": { "kind": "Name", "value": "avatarUrl" }, "selectionSet": null } ] } } ] } } |} let parsed_selection_set = your_json_string |> Yojson.Basic.from_string |> member "selectionSet" |> parse_selection_set
Running this will convert your JSON into an OCaml selection_set record with all the nested selections properly parsed.
内容的提问来源于stack exchange,提问作者Shuumatsu

