SML で演算子をデータ型として定義すると、それらは演算子としての関数として機能しますか?
お気に入りdatatype egexp= egadd of egexp*egexp
egadd は演算子または関数として機能しますか? つまり、式 a+b を egadd(a)(b) または (a)egadd(b) と書くのですか?
ありがとうございました
あなたは本質的に中置構文について尋ねています。これは実際には関数とコンストラクターとは何の関係もありません。どちらも infix または (デフォルトで) nonfix のいずれかです。
fun f (x, y) = ...
val a = f (1, 2)
infix f
val b = 1 f 2
datatype t = C of int * int
val c = C (1, 2)
infix C
val d = 1 C 2
これは、英数字および記号識別子に一様に適用されます。
fun ++ (x, y) = ...
val a = ++ (1, 2)
infix ++
val b = 1 ++ 2
datatype t = && of int * int
val c = && (1, 2)
infix &&
val d = 1 && 2
つまり、SML では「関数」と「演算子」の区別はありません。非固定識別子と中置識別子があります。
あなたはどちらも書きません。指定した型を取って、「関数」に作用します (実際には、値コンストラクターとして)。
つまり、 が をegadd
取ると指定したのでegexp * egexp
、2 つの のタプルegexps
、つまり: を取ります。egadd (a, b)
ここで、a
とb
は型の値ですegexp
。
infix
必要に応じて、またはを使用して、他の関数と同様に中置にすることができますinfixr
。
egadd
「コンストラクタ」です。egexp
は代数データ型でありegadd
、そのコンストラクタの 1 つです。SML のコンストラクターは、引数を持たないか、引数を 1 つ持つことができます (複数の「コンポーネント」を 1 つのタプル引数にパックできます)。引数を持つコンストラクタとして、egadd
はその引数型 ( egexp*egexp
) の引数を取り、代数データ型 の値を返す (「構築」)関数でもありますegexp
。たとえば、@SebastianPaaskeTørho が述べたように、a
とb
が type の値である場合、 type の新しい値egexp
をegadd (a, b)
構築しますegexp
。