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