プログラミング言語SML#解説 3.7.1版
19

19.24 動的型キャスト式 _dynamic exp as ty

この式は動的型付けされた値exptyにキャストする. expの型はτ Dynamic.dynで なければならない. この式の型はtyである.

この式を評価すると,expが評価され, 動的型付けされた値vを得る. この式の値は,vの構造とtyに依存して決まる. その規則は以下の通りである.

  • tyDynamic.void Dynamic.dynのとき, この式の値はvである.

  • tyτ Dynamic.dyn型のとき, vτ型のビューを持つ(vの部分構造をτ型の値として取り出せる) ならば,この式の値はvである. そうでなければDynamic.RuntimeTypeError例外を発生させる.

  • tyDynamic.dyn型を含まないとき, vの型がtyと一致するならば,この式の値は vty型にキャストした値である. そうでなければDynamic.RuntimeTypeError例外を発生させる.

  • tyDynamic.dyn型を含む型のとき, vおよびtyの構造に対して再帰的に以上の規則を適用する.

例えば,以下のようにして作ったレコードのリストに対して

val r = Dynamic.dynamic [{name = "Joe", age = 21}, {name = "Sue", age = 31}];

以下のキャストは全て正しい.

_dynamic r as {name:string, age:int} list;
_dynamic r as {name:Dynamic.void Dynamic.dyn, age:int} list;
_dynamic r as Dynamic.void Dynamic.dyn;
_dynamic r as Dynamic.void Dynamic.dyn list;
_dynamic r as {name:string, age:int} Dynamic.dyn list;
_dynamic r as {name:string} Dynamic.dyn list;
_dynamic r as {name:string, age:int} list Dynamic.dyn;
_dynamic r as {age:int} list Dynamic.dyn;

v自体は必ずしもMLで型がつく構造でなくてもよい. 例えば以下のようにして作ったヘテロジニアスなリストに対して

val l = Dynamic.fromJson
          "[{\"name\":\"Joe\", \"age\":21},\
          \{\"name\":\"Sue\", \"grade\":2.0},\
          \{\"name\":\"Robert\", \"nickname\":\"Bob\"}]";

以下のキャストは全て正しい.

_dynamic l as Dynamic.void Dynamic.dyn;
_dynamic l as Dynamic.void Dynamic.dyn list;
_dynamic l as {name:string} Dynamic.dyn list;
_dynamic l as {name:string} list Dynamic.dyn;
_dynamic l as {name:Dynamic.void Dynamic.dyn} Dynamic.dyn list;

この式を分割コンパイルモードで用いる場合, "reify.smi"_requireする必要がある.