プログラミング言語SML#解説 4.1.0版
13 SML#の拡張機能:動的型付け機構とJSONの型付き操作

13.2 項と型のリーフィケーション

静的型付き言語では一般に,型情報はコンパイラのみが管理するメタな 情報であり,型情報はコンパイル後のコードにはデータ構造として含まれません. また,値のメモリ上のデータ構造も,型によって決められるメタな 情報です. これらメタな情報をコードが扱えるオブジェクトとして取り出すことを リーフィケーションと言います. SML#の動的型付けは,このリーフィケーションを基盤として 構築されています. ユーザーもこのリーフィケーション機構を利用して,型情報や 値の内部構造を,MLのdatatypeとして取り出すことができます.

SML#は以下の関数を提供します.

  • Dynamic.dynamicToTerm : Dynamic.void Dynamic.dyn -> Dynamic.term. この関数は, 動的に型付けされた値から値の構造をDynamic.term型の項表現として 取り出します. Dynamic.term型は一般的なMLのdatatypeであり,他のdatatypeと 同様,MLのcase式などで分析することができます.

  • Dynamic.dynamicToTy : Dynamic.void dyn -> Dynamic.ty. この関数は, 動的に型付けされた値から型情報をDynamic.ty型の項表現として 取り出します. Dynamic.term型と同様に,Dynamic.ty型もごく一般的な MLのdatatypeです.

  • Dynamic.termToDynamic : Dynamic.term -> Dynamic.void Dynamic.dyn. この関数は 項表現を動的に型付けされた値に変換します. _dynamic構文と組み合わせることで,Dynamic.term型 の値として構築された構造を,MLの静的型付けされた値に変換することが可能です.

以下の対話セッションは,Dynamic.term型を通じてMLのレコードから 別の型のレコードを構築する例です.

# open Dynamic;
...
# val x = {name = "Sendai", wind = 7.6};
val x = {name = "Sendai", wind = 7.6} : {name: string, wind: real}
# val d = dynamicToTerm (dynamic x);
val d = RECORD {#name => STRING "Sendai", #wind => REAL64 7.6} : term
# case d of
>   RECORD m =>
>   RECORD (RecordLabel.Map.insert
>             (m, RecordLabel.fromString "weather", STRING "cloudy"))
>   | x => x;
val it =
  RECORD
  {#name => STRING "Sendai", #weather => STRING "cloudy", #wind => REAL64 7.6}
  : term
# termToDynamic it;
val it = _ : void dyn;
# _dynamic it as {name:string, wind:real, weather:string};
val it =
  {name = "Sendai", weather = "cloudy", wind = 7.6}
  : {name: string, weather: string, wind: real}