プログラミング言語SML#解説 4.0.0版
9 SML#の拡張機能:その他の型の拡張

9.3 第一級オーバーローディング

MLでよく使われる組込み演算は,オーバーロードされています. 例えば,加算演算子+は,int, real, wordなどを含む型の 加算に使用できます.

# 1 + 1;
val it = 2 : int
# 1.0 + 1.0;
val it = 2.0 : real
# 0w1 + 0w1;
val it = 0wx2 : word

この+は多相関数と違い,適用される値によって対応する組込 み演算(上の例の場合Int.+, Real.+, Word.+のどれか)が選択されます. Standard MLでは,このオーバーロード機構はトップレベルで解決する戦 略がとられています. トップレベルでもオーバーロードが解消しなかった場合,コンパイラはあ らかじめ決められた型を選択します. 例えば,関数

fun plus x = x + x

を定義すると,演算子のオーバーロードを解決するためのxに関する型情報 がないため,あらかじめ決められているint型が選択されます.

この戦略は,データベースの問い合わせ言語をシームレスに取り込む上 で,大きな制約となります. SQLで提供されている種々の組込み演算の多くは,データベースのカラ ムに格納できる型に対してオーバーロードされています. これらの演算子の型をすべてSQL式が書かれた時点で決定してしまうと, SQLの柔軟性が失われ,SML#からデータベースを柔軟に使用する上での利 点を十分に活かすことができません. そこでSML#では,オーバーロードされた演算子を,第一級の関数 と同様に使用できる機構を導入しています. オーバーロードされた演算子を含む式は,その演算子が対応可能な型に関 して多相的になります. 例えば関数plusに対して以下のような型が推論されます.

# fun plus x = x + x;
val plus = fn : [’a::{int, word, int8, word8, ...}. ’a -> ’a]

この関数は,型変数’aint, word, int8, word8, int16, word16, int64, word64, intInf, real, real32int16以下は省略されています) の何れかを代入しえ得られる型をもつ関数として使用できます. 型変数に付加されている制約::{...}は,オーバーロード演算子 に許される型に制限があるための制約です.