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}