[[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

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS