§ 8.7. 多相バリアントの表現
レコード構造は,各要素に名前を付けたデータ構造です. この構造の双対をなす概念にラベル付きバリアントがあります. 多くの方にとって不慣れな概念と思われますが,必要とされる機能はレ コードとほぼ同一であるため,多相レコードが表現できれば,多相バリアントも 表現できます. 多相バリアントに興味のある方への参考に,以下,その考え方とコード 例を簡単に紹介します.
レコードが名前付きのデータの集合であるのに対して,ラベル付きバリ アントは,名前付きの処理の集合の下での処理要求ラベルのついたデータと考え ることができます. 直行座標系と極座標系の両方のデータを扱いたい場合を考えます. それぞれのデータは処理の仕方がちがいますから,データにどちらの座 標系かを表すタグ(名前)を付けます. これらデータを多相関数と一緒に使用できるようにする機構が多相バリ アントです. これは,バリアントタグを,メソッド集合から適当なメソッドを選び出 すセレクタと考えると,多相レコードを使って表現できます. 同一の点の2つのそれぞれの座標系での表現は,例えば以下のようにコー ド可能です.
# val myCPoint = fn M => #CPoint M {X = 1.0, Y = 1.0};
val myCPoint = fn : ['a#{CPoint: {X: real, Y: real} -> 'b}, 'b. 'a -> 'b]
# val myPPoint = fn M => #PPoint M {r = 1.41421356, theta = 45.0};
val myPPoint = fn : ['a#{PPoint: {r: real, theta: real} -> 'b}, 'b. 'a -> 'b]
つまりタグ
val distance =
{
CPoint = fn {x, y, ...} => Real.Math.sqrt (x * x + y * y),
PPoint = fn {r, theta, ...} => r
};
多相バリアントデータをメソッドスイートに適用することによって起動できます.
# myCPoint distance ;
val it = 1.41421356 : real
# myPPoint distance ;
val it = 1.41421356 : real
これによって,表現の異なるデータのリストなどを多相関数によって安 全に処理できるようになります.