りはびり(Ordシグネチャーとファンクターを使って独自のTreeモジュールを作る)
久しぶりにOCamlでも書いてみようかと思ったら、全然書けなくなっていたのでリハビリをすることに。
お題は @osiire さんの
http://d.hatena.ne.jp/osiire/20101101
のレベル3。
といってもこれまでの経験上、最初の「Ordシグネチャーとファンクターを使って独自のTreeモジュールを作る」っぽいことしかやったことがないので、実はリハビリと称してやったことがないことに挑戦させる作戦。
まぁ、ファンクタの記法どころかシグネチャの書き方さえ忘れているので、まずは本当にリハビリ。Set.mlのコードとかをカンニングしつつ。
module type OrderedType = sig type t val compare : t -> t -> int end module MakeTree (Ord : OrderedType) = struct type t = Lf | Br of t * Ord.t * t let init () = Lf let rec add tree x = match tree with | Lf -> Br (Lf, x, Lf) | Br (left, v, right) -> if Ord.compare x v < 0 then Br ((add left x), v, right) else Br (left, v, (add right x)) let tree_of_list l = List.fold_left (fun a x -> add a x) (init ()) l let list_of_tree tree = let rec loop tree l = match tree with | Lf -> l | Br (left, v, right) -> loop right ((loop left l) @ [v]) in loop tree [] end module IntTree = MakeTree ( struct type t = int let compare a b = a - b end ) module FloatTree = MakeTree ( struct type t = float let compare a b = if a = b then 0 else (if a < b then -1 else 1) end ) let _ = let int_tree = IntTree.tree_of_list [8; 2; 6; 1; 9; 3; 7; 4; 5] in List.iter (fun x -> Printf.printf "%d " x) (IntTree.list_of_tree int_tree); print_newline () let _ = let float_tree = FloatTree.tree_of_list [1.0; 3.5; 1.5; 4.0; 0.5; 2.5; 2.0; 3.0] in List.iter (fun x -> Printf.printf "%f " x) (FloatTree.list_of_tree float_tree); print_newline ()
でけたようにみえる。
komamitsu@onion:~/lab/ocaml/tree$ ocaml tree.ml 1 2 3 4 5 6 7 8 9 0.500000 1.000000 1.500000 2.000000 2.500000 3.000000 3.500000 4.000000