関数のアリティ (arity)

関数のアリティは関数が取る引数の数です。 しばしばアリティが 0, 1, 2, 3 の関数はそれぞれ、nullary, unary, binary, ternary 関数と呼ばれます。 例えば、次の関数 sqrsum1 は binary 関数で、2つの引数の型は int です:

fn sqrsum1 (x: int, y: int): int = x * x + y * y

unary関数 sqrsum2 を次のように定義することができます:

// typedef int2 = (int, int) // fn sqrsum2 (xy: int2): int = let val x = xy.0 and y = xy.1 in x * x + y * y end // end of [sqrsum2]

キーワード typedef は名前 int2 とタプル型 (int, int) を束縛します。 別の言い方をすると int2(int, int) の略語しくは別名として取り扱われます。 関数 sqrsum2int2 型のタプルを引数として1つだけ取るunaryです。 sqrsum21~1 から成るタプルに適用するには、 sqrsum2 @(1, ~1) と書く必要があります。 もし単純に sqrsum2 (1, ~1) と書いた場合、 型検査器は関数のアリティが合わないというエラーを出力します。 型検査器は sqrsum2 に (1つのペアではなく) 2つの引数が適用されたと見なしてしまうためです。

(Haskell や ML のような) 多くの関数型言語は unary 関数のみを許しています。 これらの言語において、複数の引数を取る関数はエンコードして表現します。 つまり、タプルを唯一の引数として取る unary 関数か、 カリー化された関数に連続してそれらの引数を渡すようにして実現されています。 けれども、ATS は複数引数を持つ関数を直接サポートしています。 ATS でも可変長引数の関数を限定的にサポートしています。 これはつまり引数の数が不定の関数です (例えばC言語の printf 関数が有名です)。 この話題は別の章で取り上げます。