Chapter 4. 結合性宣言

関数 f が与えられたとき、f を引数 v に適用する標準的な構文は f(v) です; 2つの引数 v1v2 に適用する構文は f(v1, v2) です。 また、引数が2つの関数適用のための中置記法と、引数が1つの関数適用のための前置/後置記法が ATS では許されています。

ATS におけるそれぞれの識別子には次の結合性の内1つを割り当てることができます: 前置 (prefix), 中置 (infix), 後置 (postfix) です。 多くの一般に使われる識別子の結合性宣言を prelude/fixity.ats から見ることができます。 しばしば、結合性が割り当てられた識別子を 演算子 と呼びます。 例えば、次の構文で宣言している +- は優先順位 50 の中置演算子です:

infixl 50 + -

この宣言によって、1 + 2 - 3 のような式を書くことができます。 この式は、標準的な関数適用構文の観点から -(+(1, 2), 3) のように構文解析されます。

キーワード infixl は宣言した中置演算子が左結合であることを示しています。 右結合と無結合の中置演算子には、それぞれキーワード infixrinfix を使ってください。 もし結合性宣言の優先順位を省略した場合、0 であると見做されます。

また、iadd, fadd, padd, uadd+ 演算子と等しい優先順位を持つ左結合中置演算子であることを宣言するのに次の構文を使うことができます:

infixl (+) iadd fadd padd uadd

これは数多く宣言された演算子の優先順位を思い出すのが困難な場面で実際に有用です。 ときには、演算子の優先順位をもう一つの演算子の優先順位と関連を持たせて指定したくなることがあります。 例えば、次の構文は opr2 が左結合中置演算子で、その優先順位は opr1 の優先順位に 10 加えたものであると宣言しています:

infixl (opr1 + 10) opr2

もしプラス記号 (+) をマイナス記号 (-) に変えると、opr2 の優先順位は opr1 の優先順位から 10 減じたものになります。

また、識別子 opr の前にバックスラッシュ記号 () を付けると、優先順位 0 の無結合中置演算子にすることもできます。 例えば、式 exp1 opr exp2opr (exp1, exp2) を表わします。 このとき、exp1exp2 はなんらかの静的もしくは動的な式です。

(引数が1つの) 前置演算子と後置演算子を宣言する構文は同じです。 例えば、次の構文は ~? をそれぞれ優先順位 61 の前置演算子と、優先順位 69 の後置演算子として宣言しています:

prefix 61 ~ postfix 69 ?

例として、次の3行プログラムでは後置演算子を使っています:

postfix (imul + 10) !! extern fun !! (x: int): int implement !! (x) = if x >= 2 then x * (x - 2)!! else 1

演算子の前にキーワード op を単純に付けることで、その演算子に割り当てられた結合性設定を無効化することができます。 例えば、1 + 2 - 3op- (op+ (1, 2), 3) のように書くことができます。 また、演算子に割り当てられた結合性設定を (永久に) 無効化することも可能です。 例えば、次の構文は演算子 iadd, fadd, padd, uadd に対して結合性設定を無効化します:

nonfix iadd fadd padd uadd

nonfix は ATS のキーワードであることに注意してください。

最後に、それぞれの結合性宣言はそのスコープ内でのみ効力を持つことに注意してください。