13.1 動的型付け
動的型付き言語では,値の型を実行時に分析し,その型に応じた処理を 行うことができます. 動的型付き言語における値は,型を表す実行時表現とその型に応じ た値とを持つ,一様な形式のデータとみなせます. SML#は, この型情報を伴う値の表現を,静的型付き言語であるMLから取り扱う 機構を提供します.
Dynamic.void Dynamic.dynは,動的に型付けされた値の型です. 型引数Dynamic.voidの意味は後述します. この型に対して,以下の基本的な演算が定義されています.
-
•
関数 Dynamic.dynamic : [’a#reify. ’a -> Dynamic.void Dynamic.dyn]. この関数は任意のMLの値から動的型付けされた値を作ります. ’a#reifyは,’aのインスタンスの実行時型情報 が必要であることを表します. 他のカインドと異なり,reifyカインドは型変数が動く範囲を 制限しません.
-
•
式 _dynamic as . この式は,動的型付けされた値の型情報を実行時に 検査し,その値を型にキャストします. キャストに失敗した場合は実行時例外 Dynamic.RuntimeTypeErrorが発生します.
さらに以下の式が用意されています.
_dynamiccase of => | | =>
この式は, 動的型付けされた値に対して動的型検査を伴うパターンマッチを 行います. パターンには,任意のパターンを書くことができます. ただし,変数パターンには必ず型注釈を書く必要があります.
以下の対話セッションは,ヘテロジニアスなリストとそれを処理する 関数の例です.
# val x = Dynamic.dynamic {name = "Sendai", wind = 7.6};
val x = _ : Dynamic.void Dynamic.dyn
# val y = Dynamic.dynamic {name = "Shiroishi", weather = "Sunny"};
val y = _ : Dynamic.void Dynamic.dyn
# val z = Dynamic.dynamic {name = "Ishinomaki", temp = 12.4};
val z = _ : Dynamic.void Dynamic.dyn
# val l = [x, y, z];
val l = [_, _, _] : Dynamic.void Dynamic.dyn list
# fun getName r = _dynamiccase r of {name:string, ...} => name;
val getName = fn : [’a. ’a Dynamic.dyn -> string]
# map getName l;
val it = ["Sendai", "Shiroishi", "Ishinomaki"] : string list
# fun getTemp r =
> _dynamiccase r of
> {temp:real, ...} => SOME temp
> | _ : Dynamic.void Dynamic.dyn => NONE;
val getTemp = fn : [’a. ’a Dynamic.dyn -> real option]
# map getTemp l;
val it = [NONE, NONE, SOME 12.4] : real option list
レコードに限らず,データ型,関数,不透明な型など任意の型の値を 動的型付けされた値にしたり,静的型付けされた値に戻したりすることができます.