多相関数はどちらかといえば関数テンプレートに似ています。 けれども、前者は ATS における第一級の値ですが後者は違います。 例として次に定義する関数 swap_boxed は多相的です:
型変数 a と b はしばしば静的引数と呼ばれ、 xy は動的引数と呼ばれます。 例えば、次のコードは多相関数 swap_boxed を使っています:val AB = (box("A"), box("B")) val BA1 = swap_boxed{boxstr,boxstr} (AB) val BA2 = swap_boxed (AB) // omitting type arguments may be fine
多相関数を呼び出す時、静的引数を省略してコンパイラによって推論されることをしばしば期待します。 けれども推論に失敗したり、推論がプログラマが意図していたものとは違っているために、明示的に静的引数を指定することが必要になることも珍しくはありません。
次の多相関数の実装スタイルのように、静的引数を連続して渡すことも可能です:
// fun swap2_boxed{a:type}{b:type} (xy: (a, b)): (b, a) = (xy.1, xy.0) // val AB = (box("A"), box("B")) val BA1 = swap2_boxed (AB) // both static arguments to be synthesized val BA2 = swap2_boxed{...} (AB) // both static arguments to be synthesized val BA3 = swap2_boxed{..}{boxstr} (AB) // 1st static argument to be synthesized val BA4 = swap2_boxed{boxstr}{..} (AB) // 2nd static argument to be synthesized val BA5 = swap2_boxed{..}{..} (AB) // both static arguments to be synthesized val BA6 = swap2_boxed{boxstr}{boxstr} (AB) // both static arguments are provided //
実際の場面で非常に一般的な多相関数に由来する2種類のエラーを見たことがあります:
1番目の種類は次のような例です:
型変数 a と b の種が type の代わりに t@ype であることに注意してください。 この例は型検査には通りますが、コンパイル時に起きるエラーは、多くのプログラマにとって不可解なものでしょう。 このエラーを発生させる単純な理由は、コンパイラが a と b のサイズを算出できないことです。 種 t@ype のC言語コードを生成しようとした時、型のサイズが特定できないのです。2番目の種類は次のような例です:
厳密に言えば、実際にはこの例にエラーはありません。 もしこのような定義がされると、swap_boxed は多相関数の代わりに関数テンプレートになります。 けれども、このような関数テンプレートはボックス化されていない型でインスタンス化できず、使用が制限されています。 これが意図したものでなければ、好ましくないでしょう。