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

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 exp as τ. この式は,動的型付けされた値expの型情報を実行時に 検査し,その値をτ型にキャストします. キャストに失敗した場合は実行時例外 Dynamic.RuntimeTypeErrorが発生します.

さらに以下の式が用意されています.

_dynamiccase exp of dpat1 => exp1 | | dpatn => expn

この式は, 動的型付けされた値expに対して動的型検査を伴うパターンマッチを 行います. パターンdpatiには,任意のパターンを書くことができます. ただし,変数パターンには必ず型注釈を書く必要があります.

以下の対話セッションは,ヘテロジニアスなリストとそれを処理する 関数の例です.

# 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

レコードに限らず,データ型,関数,不透明な型など任意の型の値を 動的型付けされた値にしたり,静的型付けされた値に戻したりすることができます.