14.4 型の隠蔽
前節の例から理解されるとおり,インターフェイスファイルの基本的考え 方は,以下のとおりです.
-
1.
datatypeやexceptionなどのコンパイル時に定義される資源 (静的資源)は,将来そのインターフェイスファイルで定義される実体そのものを 記述する.
-
2.
関数や変数などの実行時の値を表すものは,その型のみを宣言する.
これら情報が,コンパイラがこのインターフェイスファイルを使う別のソー スコードをコンパイルする上で必要かつ十分な情報です. しかし,この原則だけでは,Standard MLのモジュールシステムが提供 する型情報の隠蔽の機能を使うことができません. 例えば,前節のインターフェイスファイルqueue.smiでは,’a queueの実装が,Q of ’a list * ’a listと定義され公開されていま すが,この実装の詳細は隠蔽したい場合が多いと思われます.
この問題の解決のために,インタフェイスファイルに
type (= ) (* 括弧はそのまま記述する *)
eqtype (= ) (* 括弧はそのまま記述する *)
の形の隠蔽された型の宣言を許しています. この宣言は,型が定義されその実装の表現はであるが, その内容はこのインターフェイスの利用者からは隠されることを表しています. シグネチャ同様,type宣言は,同一性判定を許さない型,eqtypeは同一性判定が可能な型を表します. には, を実装する型の型コンストラクタを指定します. 例えば,
type t1 = int
type t2 = int list
type ’a t3 = (’a * ’a) array
という実装に対して,インターフェースファイルは
type t1 (= int)
type t2 (= list)
type ’a t3 (= array)
と書きます. 実装型がレコード型,組型,関数型ならば, にはそれぞれ{},*,->を指定します. 実装型がdatatypeで定義された型ならば,コンストラクタの 定義に応じて以下のいずれかを指定します.
-
•
unit. 引数を持たないコンストラクタだけからなり,かつコンストラクタが 1つしか存在しない.
-
•
contag. 引数を持たないコンストラクタだけからなり,かつコンストラクタが2つ 以上存在する.
-
•
boxed. 上記のいずれにも当てはまらない.
例えば,queue.smiのdatatype ’a queue宣言のかわりに
type ’a queue (= boxed)
と書くことができます.
さらに,シグネチャの場合同様,インターフェイスファイルは,そのイン ターフェイスを実装するソースが定義する変数をすべて網羅している必要はありま せん. インターフェイスに宣言されたもののみが,そのインターフェイスを_require宣言を通じて利用するユーザに見えるようになります.