SML#のJSONサポートについては[Ohori et al., ECOOP'16]に詳しく書かれているので,読んで試してみました.
今回はSML# 3.2.0を使用しました.
パース
json.smi
に定義されているJSON
ストラクチャのimport
関数は,JSON文字列をパースして,型付きJSONを計算します.
val json = JSON.import "[1, 2]"
型付きJSONの値であるjson
はJSON.void JSON.dyn
という謎の型を持っていて,このままだと使えません.
使いやすい型に変換
_json e as τ
という構文を使うことで,型τ
に変換することができます.
型τ
に変換可能かどうかは動的にチェックされます.
val list = _json JSON.import "[1, 2]" as int list;
val record = _json JSON.import "{\"foo\": 1, \"bar\": \"2\"}" as { foo: int, bar: string };
val heterogeneousList = _json JSON.import "[42, \"57\"]" as JSON.void JSON.dyn list;
val a = _json List.nth (heterogeneousList, 0) as int;
val b = _json List.nth (heterogeneousList, 1) as string;
heterogeneousなリストも扱うことができています.
パターンマッチ
_jsoncase e of jp1 => e1 | · · · | jpn => en
という構文を使うことで,型付きJSONの値に対してパターンマッチを行うことができます.
val heterogeneousList = _json JSON.import "[{\"pi\": 3.141592, \"grothendieck\": 57}, \"42\"]" as JSON.void JSON.dyn list;
val result = map (fn x => _jsoncase x of
{pi : real, grothendieck : int} => Real.toString pi ^ " " ^ Int.toString grothendieck
| str : string => str
| _ => "")
heterogeneousList;
まとめ
型の恩恵を受けつついい感じにJSONを処理できます.
とても良い.