プログラミング言語 Standard ML 入門 (問題の解答例)
7 データ構造の定義と利用

7.5 データ型を使用したプログラミング例

問 7.10

キーと値の組のリストを受け取り,それらを含む辞書を作成する関数

    val makeDict : (string, ’a) list -> ’a dict

を定義し,それを使って辞書を作成し,上記関数のテストを行え.

解答例  makeDict関数の定義例は以下の通り。各関数のテストは省略。

   fun makeDict L =
      foldr
        (fn ((key, v), dict) => enter(key, v, dict))
        Empty
        L
問 7.11

上記の例はキーを string 型に制限されている. この制限を取り除く1つの方法は, string 型の比較演算を直接含む enterlookUp 関数を定義する 代わりに,比較関数を引数として受け取り,enterlookUp 関数に相当する関 数を作り出す,以下の型を持つ高階の関数 makeEntermakeLookUp を 定義することである.

   type (’a,’b) dict = (’a * ’b) tree
   val makeEnter : (’a * ’a -> order) -> ’a * ’b * (’a,’b) dict -> (’a,’b) dict
   val makeLookUp : (’a * ’a -> order) -> ’a * (’a,’b) dict -> ’b

上記の関数を定義し,テストを行え.

解答例  makeEnterの型は、foldlなどと一緒に使うことを考えると、

   val makeEnter : (’a * ’a -> order) -> (’a * ’b) * (’a,’b) dict -> (’a,’b) dict

の方が便利である。 そこで、この型の関数として定義例を以下に示す。

   fun makeEnter f ((k, v), Empty) = Node((k,v), Empty, Empty)
     | makeEnter f ((k, v), dict as Node((k’,v’),L,R)) =
       (case f (k,k’) of
           EQUAL => dict
         | GREATER => Node((k’,v’), L, makeEnter f ((k,v), R))
         | LESS => Node((k’,v’), makeEnter f ((k,v),L), R))
   fun makeLookUp f (k, Empty) = NONE
     | makeLookUp f (k, dict as Node((k’,v’),L,R)) =
       (case f (k,k’) of
           EQUAL => SOME v’
         | GREATER => makeLookUp f (k, R)
         | LESS => makeLookUp f (k, L))
問 7.12

makeEntermakeLookUp を使って, int 型データをキーとし,string 型データを値として持つ (int,string) dict 型の辞書の操作関数を作成し, テストを行え.

解答例  SML#での定義とテストの例を以下に示す。

   # fun enterIntDict x = makeEnter Int.compare x;
   val enterIntDict = fn : [’a. (int * ’a) * (int * ’a) tree -> (int * ’a) tree]
   # fun lookUpIntDict x = makeLookUp Int.compare x;
   val lookUpIntDict = fn : [’a. int * (int * ’a) tree -> ’a option]
   # val D = foldl enterIntDict Empty [(1,"1"), (2, "2"), (3, "3")];
   val D =
     Node
     ((1, "1"), Empty, Node ((2, "2"), Empty, Node ((..., ...), Empty, Empty)))
     : (int * string) tree
   # val items = map (fn x => lookUpIntDict (x, D)) [1,2,3,4]
   val items = [SOME "1", SOME "2", SOME "3", NONE] : string option list