[[OCamlテクニック/hlist]] *オブジェクトとサブタイピングを利用した例。 [#ub39884e] (* 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 *マニア向け [#p76e276f] 超トリッキーにすれば、存在型を含むオブジェクトのヘテロリストも作れます。 (* 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] (*へテロリスト!*) - 宿題のへテロなリストです。こんなコードがスグに書けなくてスミマセン。 - オブジェクトの方がなるほどという感じです。showable (new integer 10) ってどう読めば? -- [[けいご]] &new{2006-12-01 (金) 13:46:37}; - やっぱり積(objectとかレコードとか)の方が直感的ではありますよね。和(variant)の方の多相性も便利なんですが。ところで showable (new integer 10) の読み方ですか? 発音? -- [[ogasawara]] &new{2006-12-01 (金) 17:33:26}; - LVvgJJNWRp -- [[amowulzvras]] &new{2008-09-26 (金) 22:49:32}; - IrgIgRlCTxC -- [[djwimbatimr]] &new{2008-09-26 (金) 22:49:55}; #comment