structure signature functor
この3つはSML最大の難所だった。というのは当時はC言語しか知らなかったから。JavaとC++(のtemplate)を理解してたらずっと理解しやすかったに違いない。structureはクラス、signatureはインタフェース、functorはパラメトリッククラスって割り当てて進めていく感じで。もちろんstructureはインスタンスの型定義ってわけだけでもないんだけど。
ocamlではstructureはmoduleらしい。意味はこっちのほうがわかりやすいかも。
例:
module MyLinkList = struct type 'a myList = Empty | Node of 'a * 'a myList exception ListIsEmpty let newList = Empty let rec add this item = match this with Empty -> Node(item, Empty) | Node(value, trailer) -> Node(value, (add trailer item)) let rec get this index = match this with Empty -> raise ListIsEmpty | Node(value, trailer) -> if index = 0 then value else (get trailer (index - 1)) end;; let my_list = MyLinkList.newList;; let my_list = MyLinkList.add my_list 0;; let my_list = MyLinkList.add my_list 10;; let my_list = MyLinkList.add my_list 20;; let my_list = MyLinkList.add my_list 30;; open Printf;; printf "index 2 of my_list is %d\n" (MyLinkList.get my_list 2);;
signatureはmodule typeでこちらも意味がわかりやすい。
module type MyList = sig type 'a myList exception ListIsEmpty val newList : 'a myList val add : 'a myList -> 'a -> 'a myList val get : 'a myList -> int -> 'a end;; module MyLinkList : MyList = struct type 'a myList = Empty | Node of 'a * 'a myList exception ListIsEmpty let newList = Empty let rec add this item = match this with Empty -> Node(item, Empty) | Node(value, trailer) -> Node(value, (add trailer item)) let rec get this index = match this with Empty -> raise ListIsEmpty | Node(value, trailer) -> if index = 0 then value else (get trailer (index - 1)) end;; let my_list = MyLinkList.newList;; let my_list = MyLinkList.add my_list 0;; let my_list = MyLinkList.add my_list 10;; let my_list = MyLinkList.add my_list 20;; let my_list = MyLinkList.add my_list 30;; open Printf;; printf "index 1 of my_list is %d\n" (MyLinkList.get my_list 1);;
functorはパラメタライズされたmoduleで
module type MyList = sig type 'a myList exception ListIsEmpty val newList : 'a myList val add : 'a myList -> 'a -> 'a myList val get : 'a myList -> int -> 'a end;; module MyLinkList : MyList = struct type 'a myList = Empty | Node of 'a * 'a myList exception ListIsEmpty let newList = Empty let rec add this item = match this with Empty -> Node(item, Empty) | Node(value, trailer) -> Node(value, (add trailer item)) let rec get this index = match this with Empty -> raise ListIsEmpty | Node(value, trailer) -> if index = 0 then value else (get trailer (index - 1)) end;; module MyListList : MyList = struct type 'a myList = 'a list exception ListIsEmpty let newList = [] let rec add this item = match this with [] -> [item] | value :: trailer -> value :: (add trailer item) let rec get this index = match this with [] -> raise ListIsEmpty | value :: trailer -> if index = 0 then value else (get trailer (index - 1)) end;; open Printf;; module TestMyList (AnyMyList : MyList) = struct let createList = let my_list = AnyMyList.newList in let my_list = AnyMyList.add my_list 0 in let my_list = AnyMyList.add my_list 10 in let my_list = AnyMyList.add my_list 20 in let my_list = AnyMyList.add my_list 30 in my_list let print2nd my_list = printf "index 1 of my_list is %d\n" (AnyMyList.get my_list 1) end;; module TestMyLinkList = TestMyList(MyLinkList);; let my_list = TestMyLinkList.createList;; TestMyLinkList.print2nd my_list;;