Ch.11 SML#分割コンパイルシステム

§ 11.5. シグネチャの扱い

Standard ML言語では,第11.3節で説明した資源以 外に,シグネチャも名前の付いた資源です. 例えば,Queueストラクチャに対しては,QUEUEシグネチャ が定義されていると便利です. SML#のインタフェイスのRequire宣言には,以下の構文により, シグネチャファイルの使用宣言も書くことができます.

_require sigFilePath

sigFilePathはシグネチャファイルのパス名です. この機構を理解するために,Standard MLのシグネチャの以下の性質を 理解する必要があります.

  • シグネチャは,他のstructureで定義された型(の実体)の参照を含むこ とができる.

  • シグネチャ自身は,型(の実体)を生成しない.

SML#コンパイラは,_require sigFilePath宣言を以下 のように取り扱います.

  • シグネチャ以外のすべてのRequire宣言の下で,sigFilePathファイルで 定義されたシグネチャを評価.

  • この宣言を含むインターフェイスファイルを_require宣言を通じて 利用するソースコードの冒頭で,評価済みのsigFilePathファイルが展開され ているとみなす.

11.3に,シグネチャを含み型が隠蔽された 待ち行列のインタフェイスと実装の例を示します. この例では,実装ファイルに型を隠蔽するシグネチャ制約を付けても, 利用者にとっての効果は変わりません.

queue-sig.smlファイル:

signature Queue =
sig
  datatype 'a queue = Q of 'a list * 'a list
  exception Dequeue
  val empty : 'a queue
  val isEmpty : 'a queue -> bool
  val enqueue : 'a queue * 'a -> 'a queue
  val dequeue : 'a queue -> 'a queue * 'a
end

queue.smiファイル:

_require "basis.smi"
_require "queue-sig.sml"
 
structure Queue =
struct
  type 'a queue (= boxed)
  exception Dequeue
  val empty : 'a queue
  val isEmpty : 'a queue -> bool
  val enqueue : 'a queue * 'a -> 'a queue
  val dequeue : 'a queue -> 'a queue * 'a
end

queue.smlファイル:

structure Queue : QUEUE =
struct
  datatype 'a queue = Q of 'a list * 'a list
  exception Dequeue
  val empty = Q ([],[])
  fun isEmpty (Q ([],[])) = true
    | isEmpty _ = false
  fun enqueue (Q(Old,New),x) = Q (Old,x::New)}
  fun dequeue (Q (hd::tl,New)) = (Q (tl,New), hd)
    | dequeue (Q ([],_) = raise Dequeue
    | dequeue (Q(Old,New) = dequeue (Q(rev New,[]))
end
Figure 11.3. インターフェイスファイルの例