GoF in OCaml for Advent Calendar 2012 #2
OCaml Advent Calendar二日目です。
Adapterパターンの次はBridgeパターンですが、これは継承と委譲を組み合わせる話なので前回のAdapterパターンと記述的には同じです。省略。という事で、今回はCompositeパターンをOCamlで記述してみます。
Compositeパターンは木構造を作る時に使えるらしい。共通インターフェイスを定義して枝と葉を抽象的に扱います。
module FileSystem = struct (* FileInterfaceに相当する型. Folderが子供としてtのlistを持っている. *) type t = File of string| Folder of string * t list (* 空白を出力する補助関数 *) let printDepthSpace n = for i = 0 to n - 1 do print_string " " done (* コンストラクタ *) let file name = File name let folder name = Folder (name, []) (* なんか深さを指定するprinter *) let rec defaultMethod depth t = printDepthSpace depth; match t with | File name -> print_string name; | Folder (name, children) -> print_string name; List.iter (defaultMethod (depth + 1)) children (* 子供を返す関数. 部分関数なのでoption型を返す *) let getChildren = function | File _ -> None | Folder (_, children) -> Some children (* 子供を追加する関数. *) let addComponent child = function | File _ -> None | Folder (name, children) -> Some (Folder (name, child :: children)) (* 子供を削除する関数. *) let removeComponent child = function | File _ -> None | Folder (name, children) -> Some (Folder (name, List.filter ((=) child) children)) end
直訳するとこのような感じでしょうか。getChildren, addComponent, removeComponetをFileに適用する事はできないのでNoneが返ります。
次回へ続く! -> http://d.hatena.ne.jp/osiire/20121203