プログラミング言語 Standard ML 入門 (問題の解答例)
10 モジュールシステム

10.2 モジュールのシグネチャの指定

問 10.5

FastIntQueue に 不透明な QUEUE シグネチャ制約を加えたストラクチャAbsFastIntQueueを定義し, AbsIntQueue と置き換え可能であることを確かめよ.

解答例  AbsIntQueueを使用する以下のようなコードを考える。

   signature QUEUE = sig
     exception EmptyQueue
     type queue
     val newQueue : unit -> queue
     val enqueue : int*queue -> unit
     val dequeue : queue -> int
   end
   structure AbsIntQueue = IntQueue :> QUEUE;
   structure Q = AbsIntQueue;
   val q = Q.newQueue();
   val _ = Q.enqueue(1, q);
   val _ = Q.enqueue(2, q);
   val _ = Q.enqueue(3, q);
   val a = Q.dequeue q;
   val b = Q.dequeue q;
   val c = Q.dequeue q;

SML#での実行結果は、以下の通りである。

   # structure AbsIntQueue =
     struct
       type queue  <hidden>
       exception EmptyQueue = IntQueue.EmptyQueue
       val newQueue = fn : unit -> queue
       val enqueue = fn : int * queue -> unit
       val dequeue = fn : queue -> int
     end
   # structure Q =
     struct
       type queue  <hidden>
       exception EmptyQueue = IntQueue.EmptyQueue
       val newQueue = fn : unit -> queue
       val enqueue = fn : int * queue -> unit
       val dequeue = fn : queue -> int
     end
   # val q = _ : AbsIntQueue.queue
   # val a = 1 : int
   # val b = 2 : int
   # val c = 3 : int

AbsIntQueueAbsFastIntQueueに置き換えたコードは以下の通りである。

   structure AbsFastIntQueue = FastIntQueue :> QUEUE;
   structure Q = AbsFastIntQueue;
   val q = Q.newQueue();
   val _ = Q.enqueue(1, q);
   val _ = Q.enqueue(2, q);
   val _ = Q.enqueue(3, q);
   val a = Q.dequeue q;
   val b = Q.dequeue q;
   val c = Q.dequeue q;

SML#での実行結果は、以下の通りである。

   # structure AbsFastIntQueue =
     struct
       type queue  <hidden>
       exception EmptyQueue = FastIntQueue.EmptyQueue
       val newQueue = fn : unit -> queue
       val enqueue = fn : int * queue -> unit
       val dequeue = fn : queue -> int
     end
   # structure Q =
     struct
       type queue  <hidden>
       exception EmptyQueue = FastIntQueue.EmptyQueue
       val newQueue = fn : unit -> queue
       val enqueue = fn : int * queue -> unit
       val dequeue = fn : queue -> int
     end
   # val q = _ : AbsFastIntQueue.queue
   # val a = 1 : int
   # val b = 2 : int
   # val c = 3 : int