(* showメソッドを持つ型を定義しておく *) class type showable = object method show : string end (* personとintegerはshowを持つ *) class person name = object val name : string = name method show = name end class integer i = object val value : int = i method get = value method show = string_of_int i end (* 明示的なサブタイピング *) let showable c = (c :> showable) (* へテロリスト! *) let data = [ showable (new person "ogasawara"); showable (new integer 10) ] let _ = List.iter (fun o -> print_string o#show) data
超トリッキーにすれば、存在型を含むオブジェクトのヘテロリストも作れます。
(* type t という存在型を含むオブジェクト inst を定義 *) module type Analizer = sig type t val inst : < show : t -> string; opt : unit -> t > end (* MAとRSIは存在型tとinstを持つ *) module MA : Analizer = struct type t = int let inst = object method show = string_of_int method opt () = 10 end end module RSI : Analizer = struct type t = float let inst = object method show = string_of_float method opt () = 2.0 end end (* ここで超トリッキーな型を定義 *) (* see TAPL page 377 *) type t = { f : 'y. 'y cont -> 'y } and 'y cont = { g : 'x. <show : 'x -> string; opt : unit -> 'x> -> 'y } let pack x = { f = fun cont -> cont.g x } let unpack g (x : t) = x.f g let _ = let show = { g = fun c -> print_string (c#show (c#opt ())) } in List.iter (unpack show) [pack MA.inst; pack RSI.inst] (*へテロリスト!*)