1 2class point x_init = object 3 val mutable x = x_init 4 method get_x = x 5 method move d = x <- x + d 6end;; 7 8let p = new point 7;; 9 10p#get_x;; 11p#move 3;; 12p#get_x;; 13 14let q = Oo.copy p;; 15 16q#move 7; p#get_x, q#get_x;; 17 18class color_point x (c : string) = object 19 inherit point x 20 val c = c 21 method color = c 22end;; 23 24let p' = new color_point 5 "red";; 25 26p'#get_x, p'#color;; 27 28let l = [p; (p' :> point)];; 29 30let get_x p = p#get_x;; 31let set_x p = p#set_x;; 32List.map get_x l;; 33 34class ref x_init = object 35 val mutable x = x_init 36 method get = x 37 method set y = x <- y 38end;; 39 40class ref (x_init:int) = object 41 val mutable x = x_init 42 method get = x 43 method set y = x <- y 44end;; 45 46class ['a] ref x_init = object 47 val mutable x = (x_init : 'a) 48 method get = x 49 method set y = x <- y 50end;; 51 52let r = new ref 1 in r#set 2; (r#get);; 53 54class ['a] circle (c : 'a) = object 55 val mutable center = c 56 method center = center 57 method set_center c = center <- c 58 method move = (center#move : int -> unit) 59end;; 60 61class ['a] circle (c : 'a) = object 62 constraint 'a = #point 63 val mutable center = c 64 method center = center 65 method set_center c = center <- c 66 method move = center#move 67end;; 68 69let (c, c') = (new circle p, new circle p');; 70 71class ['a] color_circle c = object 72 constraint 'a = #color_point 73 inherit ['a] circle c 74 method color = center#color 75end;; 76 77let c'' = new color_circle p;; 78let c'' = new color_circle p';; 79 80(c'' :> color_point circle);; 81(c'' :> point circle);; (* Fail *) 82fun x -> (x : color_point color_circle :> point circle);; 83 84class printable_point y = object (s) 85 inherit point y 86 method print = print_int s#get_x 87end;; 88 89let p = new printable_point 7;; 90p#print;; 91 92class printable_color_point y c = object (self) 93 inherit color_point y c 94 inherit printable_point y as super 95 method print = 96 print_string "("; 97 super#print; 98 print_string ", "; 99 print_string (self#color); 100 print_string ")" 101end;; 102 103let p' = new printable_color_point 7 "red";; 104p'#print;; 105 106class functional_point y = object 107 val x = y 108 method get_x = x 109 method move d = {< x = x + d >} 110end;; 111 112let p = new functional_point 7;; 113 114p#get_x;; 115(p#move 3)#get_x;; 116p#get_x;; 117 118fun x -> (x :> functional_point);; 119 120(*******************************************************************) 121 122class virtual ['a] lst () = object (self) 123 method virtual null : bool 124 method virtual hd : 'a 125 method virtual tl : 'a lst 126 method map f = 127 (if self#null then 128 new nil () 129 else 130 new cons (f self#hd) (self#tl#map f) 131 : 'a lst) 132 method iter (f : 'a -> unit) = 133 if self#null then () 134 else begin 135 f self#hd; 136 self#tl#iter f 137 end 138 method print (f : 'a -> unit) = 139 print_string "("; 140 self#iter (fun x -> f x; print_string "::"); 141 print_string "[]"; 142 print_string ")" 143end and ['a] nil () = object 144 inherit ['a] lst () 145 method null = true 146 method hd = failwith "hd" 147 method tl = failwith "tl" 148end and ['a] cons h t = object 149 inherit ['a] lst () 150 val h = h val t = t 151 method null = false 152 method hd = h 153 method tl = t 154end;; 155 156let l1 = new cons 3 (new cons 10 (new nil ()));; 157 158l1#print print_int;; 159 160let l2 = l1#map (fun x -> x + 1);; 161l2#print print_int;; 162 163let rec map_list f (x:'a lst) = 164 if x#null then new nil() 165 else new cons (f x#hd) (map_list f x#tl);; 166 167let p1 = (map_list (fun x -> new printable_color_point x "red") l1);; 168p1#print (fun x -> x#print);; 169 170(*******************************************************************) 171 172class virtual comparable () = object (self : 'a) 173 method virtual cmp : 'a -> int 174 end;; 175 176class int_comparable (x : int) = object 177 inherit comparable () 178 val x = x 179 method x = x 180 method cmp p = compare x p#x 181end;; 182 183class int_comparable2 xi = object 184 inherit int_comparable xi 185 val mutable x' = xi 186 method set_x y = x' <- y 187end;; 188 189class ['a] sorted_list () = object 190 constraint 'a = #comparable 191 val mutable l = ([] : 'a list) 192 method add x = 193 let rec insert = 194 function 195 [] -> [x] 196 | a::l as l' -> if a#cmp x <= 0 then a::(insert l) else x::l' 197 in 198 l <- insert l 199 method hd = List.hd l 200end;; 201 202let l = new sorted_list ();; 203let c = new int_comparable 10;; 204l#add c;; 205 206let c2 = new int_comparable2 15;; 207l#add (c2 :> int_comparable);; (* Fail : 'a comp2 is not a subtype *) 208(new sorted_list ())#add c2;; 209 210class int_comparable3 (x : int) = object 211 val mutable x = x 212 method cmp (y : int_comparable) = compare x y#x 213 method x = x 214 method setx y = x <- y 215end;; 216 217let c3 = new int_comparable3 15;; 218l#add (c3 :> int_comparable);; 219(new sorted_list ())#add c3;; (* Error; strange message with -principal *) 220 221let sort (l : #comparable list) = List.sort (fun x -> x#cmp) l;; 222let pr l = 223 List.map (fun c -> print_int c#x; print_string " ") l; 224 print_newline ();; 225let l = [new int_comparable 5; (new int_comparable3 2 :> int_comparable); 226 new int_comparable 4];; 227pr l;; 228pr (sort l);; 229let l = [new int_comparable2 2; new int_comparable2 0];; 230pr l;; 231pr (sort l);; 232 233let min (x : #comparable) y = 234 if x#cmp y <= 0 then x else y;; 235 236(min (new int_comparable 7) (new int_comparable 11))#x;; 237(min (new int_comparable2 5) (new int_comparable2 3))#x;; 238 239(*******************************************************************) 240 241class ['a] link (x : 'a) = object (self : 'b) 242 val mutable x = x 243 val mutable next = (None : 'b option) 244 method x = x 245 method next = next 246 method set_x y = x <- y 247 method set_next l = next <- l 248 method append l = 249 match next with 250 None -> 251 self#set_next l 252 | Some l' -> 253 l'#append l 254end;; 255 256class ['a] double_link x = object (self) 257 inherit ['a] link x 258 val mutable prev = None 259 method prev = prev 260 method set_next l = 261 next <- l; 262 match l with Some l -> l#set_prev (Some self) | None -> () 263 method set_prev l = prev <- l 264end;; 265 266let rec fold_right f (l : 'a #link option) accu = 267 match l with 268 None -> accu 269 | Some l -> 270 f l#x (fold_right f l#next accu);; 271 272(*******************************************************************) 273 274class calculator () = object (self) 275 val mutable arg = 0. 276 val mutable acc = 0. 277 val mutable equals = function s -> s#arg 278 method arg = arg 279 method acc = acc 280 method enter n = arg <- n; self 281 method add = 282 acc <- equals self; 283 equals <- (function s -> s#acc +. s#arg); 284 self 285 method sub = 286 acc <- equals self; 287 equals <- (function s -> s#acc -. s#arg); 288 self 289 method equals = equals self 290end;; 291 292((new calculator ())#enter 5.)#equals;; 293(((new calculator ())#enter 5.)#sub#enter 3.5)#equals;; 294((new calculator ())#enter 5.)#add#add#equals;; 295 296class calculator () = object (self) 297 val mutable arg = 0. 298 val mutable acc = 0. 299 val mutable equals = function s -> s#arg 300 method arg = arg 301 method acc = acc 302 method enter n = arg <- n; self 303 method add = {< acc = equals self; equals = function s -> s#acc +. s#arg >} 304 method sub = {< acc = equals self; equals = function s -> s#acc -. s#arg >} 305 method equals = equals self 306end;; 307 308((new calculator ())#enter 5.)#equals;; 309(((new calculator ())#enter 5.)#sub#enter 3.5)#equals;; 310((new calculator ())#enter 5.)#add#add#equals;; 311 312class calculator arg acc = object (self) 313 val arg = arg 314 val acc = acc 315 method enter n = new calculator n acc 316 method add = new calculator_add arg self#equals 317 method sub = new calculator_sub arg self#equals 318 method equals = arg 319end and calculator_add arg acc = object 320 inherit calculator arg acc 321 method enter n = new calculator_add n acc 322 method equals = acc +. arg 323end and calculator_sub arg acc = object 324 inherit calculator arg acc 325 method enter n = new calculator_sub n acc 326 method equals = acc -. arg 327end;; 328 329let calculator = new calculator 0. 0.;; 330 331(calculator#enter 5.)#equals;; 332((calculator#enter 5.)#sub#enter 3.5)#equals;; 333(calculator#enter 5.)#add#add#equals;; 334