Standard ML簡単文法 =================== ・あくまで「簡単文法」なので、授業で説明した部分のみ要約(それ以外は省 略) ・トップレベル(smlを起動して「- 」が表示された状態)では、「式」また は「定義」に「;」をつけて入力することができる ・上の「;」は「入力の終わり」という合図であって、式や定義の一部ではな い ・「式;」は「val it = 式;」の略とみなされる ---------------------------------------------------------------------- 式 ::= 1、2、345、6789、0 など (整数定数) | 0.0、12.3、4.56 など (浮動小数点定数) | "abc"、"hello" など (文字列定数) | 式1 式2 (関数適用) | 名前 (変数参照) | let 定義 in 式 end (局所定義) | fn 名前 => 式 (匿名関数) | { ラベル1 = 式1, ..., ラベルn = 式n } (レコード) | #ラベル 式 (フィールド取り出し) | case 式 of パターン1 => 式1 | ... | パターンn => 式n (パターンマッチング) | ( 式1, ..., 式n ) (組) | [ リスト1, ..., リストn ] (リスト) | ( 式1; ...; 式n ) (逐次実行) 定義 ::= val 名前 = 式 (変数定義) | fun 名前 名前1 ... 名前n = 式 (関数定義) | local 定義1 in 定義2 end (局所定義) | datatype '名前 名前 = 名前1 of 型1 | ... | 名前n of 型n (バリアント型定義) パターン ::= _ (don't care) | 名前 (変数または引数なしバリアント) | 名前 パターン (引数つきバリアント) | { ラベル1 = パターン1, ..., ラベルn = パターンn } (レコード) | ( パターン1, ..., パターンn ) (組) | [ パターン1, ..., パターンn ] (リスト) | 123、true、"abc" など (定数) 型 ::= int、real、stringなど (基本型) | 型1 -> 型2 (関数型) | ( 型 ) (括弧) | '名前 (型変数) | { ラベル1 : 型1, ..., ラベルn : 型n } (レコード型) | 型1 * ... * 型n (組型) | 名前 (バリアント型) | 型 名前 (多相データ型の具体化) ---------------------------------------------------------------------- ・「名前」とは、x、Y、z0、Abc_123、def'など、変数名・関数名や型名・コ ンストラクタになりうる文字列の総称 ・「~式」などの単項演算は、符号反転関数「~」などの適用とみなす 例: - ~ ; val it = fn : int -> int - ~123 ; val it = ~123 : int ・バリアント型の定義の「'名前」や「of 型」の部分は不要な場合は省略する ・式の中に現われるバリアント型のコンストラクタは、関数名ないし変数名と みなす 例: - datatype int_or_error = Int of int | Error ; datatype int_or_error = Error | Int of int - Int ; val it = fn : int -> int_or_error - Int 123 ; val it = Int 123 : int_or_error - Error ; val it = Error : int_or_error ・論理値定数trueとfalseは、あらかじめ datatype bool = true | false と定義されているバリアント型のコンストラクタ(引数なし)とみなす ・「if 式1 then 式2 else 式3」は「case 式1 of true => 式2 | false => 式3」とみなす ・「式1 + 式2」「式1 :: 式2」などの二項演算は、「+」「::」などの関数を、 「(式1, 式2)」という組に適用しているとみなす(中置記法という) 参考: 実際に「op +」や「op ::」のように書くと、二つ組(ペア)を引数とする 関数として「+」や「::」を使うことができる - op + ; val it = fn : int * int -> int - (op +) (1, 2) ; val it = 3 : int - (op ::) (1, [2, 3]) ; val it = [1,2,3] : int list ・同様に、「パターン1 :: パターン2」などのパターンは、「::」などのコン ストラクタが「(パターン1, パターン2)」という組に適用されているとみな す