レコード多相性

SML#は,多相型レコード計算の理論 を基礎として,レコード多相性を完全にサポートする.プログラマは,動的な名前サーチのオーバヘッドを気にすることなく,特別のデータ構造の定義や関数などを用意することなく,単に基本データ構造であるレコード操作を書くことによって,レコード多相性を自由に使うことができる.

SML#では,レコードのフィールド取り出し演算子

#<label>

およびレコードパターン

{<label>=pattern,...}

を使用した関数に対しても,以下例のように,その最も一般的な型が推論される.

# fun f x = #name x;
val f = fn : ['a, 'b#{name:'a}. 'b -> 'a]
# f {name = "Joe", age = 21};
val it = "Joe" : string

fに対して推論された型情報['a, 'b#{name:'a}. 'b -> 'a] は,この関数が,任意の型'aを値として持つnameフィールドを含む任意のレコードに適用可能な多相関数であることを示している.この中の'aは通常の型変数,'b#{name:'a} は'aの型を持つ"name"フィールドを含む任意のレコード型を表す.

このようにSML#では,特別な構文や演算を加えることなしに,レコード多相性を完全にサポートしている.したがって,プログラマは,従来要求された型宣言を省略するだけで,レコードを含む任意の構造に対しても,MLの最大の特徴である多相性を行かしたプログラムを書くことができる.

この基本機能に加え,SML#では,多相型レコード更新のための以下の構文が用意されている.

 exp # {label1 = exp1, ..., labeln = expn}

この式の評価の結果,expで表されるレコードに含まれる各ラベルlabeliの値をexniで表される値に変更した新たなレコードが作成される.例えば,ある特定のフィールドの値に1を加える関数は以下のような多相関数として定義できる.

# fun incX (x as {X,...}) = x # {X = X + 1};
val incX= fn : ['a#{X:int}.'a -> 'a]
# incX {X = 1, Y = 2};
val it = {X = 2, Y = 2} : {X:int, Y:int}

この構文は,従来のStandard MLの構文には現れないように選ばれているため,この構文の追加によって,従来のプログラムがエラーになることはない.

さらにSML#コンパイラは,これら多相型レコード演算を,常に効率よい整数オフセットによるロード演算にコンパイルする.以下はコンパイルの実例である.

# fun makeGreeting {name= {first = "David", ...},...} = "Hi, Dave"
>   | makeGreeting {name = {last,...}, ...} =  "Dear Mr./Ms." ^ last;
 Record Compiled to:
 val makeGreeting =
   ['a#{name:'b},'b#{first:string, last:string}.
     fn {$175, $174, $173, $167} =>
       bind
         $170 = $167[$175]
       in
          bind
            $171 = $170[$174]
          in
             switch
               $171
             of "David" => "Hi, Dave"
              | _ =>
                  bind
                    last = $170[$173]
                  in
                    "Dear Mr./Ms." ^ last
                  end
          end
       end
   ]

makeGreeting関数は,レコード($167)と"name","first","last"のそれぞれのフィールドのオフセットを表す3つの整数引数($175,$174,$173)を受け取る(複数引数)関数にコンパイルされている.(これらコンパイルの中間結果は,smlsharpのスイッチを指定することによって,実際にみることができる.)

Last modified:2007/03/30 10:32:12
Keyword(s):
References:[レコード多相性の理論] [SML#の特徴]