プログラミング言語SML#解説

Chapter 17. 型

本節では,型の構文およびSML#コンパイラに組み込まれている型を定義する.

型は,単相型(ty)と多相型(polyTy)に分類される. 単相型の集合は,以下の文法であたえあれる.

ty ::= tyvar 型変数名
 | {(tyrow)?} レコード型
 | ty1 *  * tyn 組型(n2)
 | ty -> ty 関数型
 | (tySeq)? longTycon (パラメタ付)きデータ型
 | (ty)
tyraw ::= lab:ty (, tyraw)? レコードフィールドの型

tyvarは,型の集合を動く変数である. 第16.2節で定義した通り'a'fooおよび ''a''fooのように表記される. 後者は同値プリミティブ演算が適用可能なeq型に限定された型変数である. eq型は,関数型とeq型ではない組み込み型(real, real32, exn) を含まない任意の型である. ユーザ定義のデータ型も,その定義に含まれる型がすべてeq型であればeq型である. 従って,例えば以下のように定義されるτ listは引数の型 τがeq型であればeq型である.

datatype 'a list = nil | :: of 'a * 'a list

関数型構成子->はラムダ計算の伝統に従い右結合する. したがって,int -> int -> intと記述すると,int -> (int -> int)と解釈される.

longTyconは,datatype宣言で定義される型構成子の 名前であり,宣言されたstructureのパス名で修飾される. int型等の基底型はパラメタtySeqを持たないデータ型である. SML#3.4.0には以下の基底型およびデータ型構成子が組み込まれている.

型構成子名 説明 eq型?
int 32ビット符号付き整数 Y
int64 64ビット符号付き整数 Y
int8 8ビット符号付き整数 Y
intInf 桁数制限のない符号付き整数 Y
word 32ビット符号なし整数 Y
word64 64ビット符号なし整数 Y
word8 8ビット符号なし整数 Y
real 浮動小数点数 N
real32 32ビット浮動小数点数 N
char 文字 Y
string 文字列 Y
exn 例外 N
unit ユニット値(()) Y
τ ref 参照(ポインタ) Y
τ array 配列 Y
τ vector ベクトル Y

多相型の集合は以下の文法で与えられる.

polyTy ::= ty
 | [boundtyvarList.ty]
 | ty -> polyTy
 | polyTy *  * polyTy
 | { (polyTyrow)? }
boundtyvarList ::= boundtyvar (, boundtyvarList)?
boundtyvar ::= tyvar(kind)?
kind ::= #{tyraw}
 | ::{tyList}
polyTyraw ::= lab:polyTy (, polyTyraw)?
  • [boundtyvarList.ty]は,束縛型変数boundtyvarList のスコープが明示された多相型である.

  • 束縛型変数は,その取りうる型の集合を制限する以下のカインド制約kindをつけることができる. レコードカインド#{ tyraw }は, tyrawが表すフィールドを含むレコード型に制限する. オーバロードカインド:: { tyList }は,インスタンス型tyListのいづれか に制限する.

この集合は,Standard MLの多相型をレコード多相性, ランク1多相,およびオーバーローディングに拡張したものである. 現在,オーバーローディングはシステム定義のプリミティブのみに限定されていおり, オーバーロカインドをもつ多相型をユーザプログラムが指定することはできない.

例えば,以下のような多相型が定義できる.

# fn x => (fn y => (x,y), nil);
val it = fn : ['a. 'a -> ['b. 'b -> 'a * 'b] * ['b. 'b list]]