(******************************************************************************) (* 2. Oh, quel beau zob j'ai ! ************************************************) (******************************************************************************) (* 2.1. Dude, where's my rec? *************************************************) (* Question 1. *) class fact = object (self) method f n = if n <= 1 then n else n * (self#f (n-1)) end;; (new fact)#f 6;; (* 2.2. Les types OCaml à la sauce objets *************************************) class virtual oo_base = object method virtual to_string : unit -> string end;; (* Question 2. *) class oo_int n0 = object inherit oo_base val mutable n : int = n0 method to_string () = string_of_int n method getn () = n method add (n' : oo_int) = new oo_int (n + (n'#getn ())) end;; (new oo_int 1664)#to_string ();; ((new oo_int 42)#add (new oo_int 9))#to_string ();; (* Question 3. *) class oo_string s0 = object inherit oo_base val mutable s : string = s0 method to_string () = s end;; (* Question 4. *) class oo_list l0 = object inherit oo_base val mutable l : oo_base list = l0 method to_string () = (List.fold_left (fun s x -> s^(x#to_string ())^"; ") "[ " l)^"]" end;; (new oo_list [ (new oo_int 16 :> oo_base) ; (new oo_int 64 :> oo_base) ])#to_string ();; (* Question 5. *) type t_string = < to_string : unit -> 'a ; gets : unit -> string ; append : 'a -> 'a ; print : unit -> unit > as 'a;; class virtual oo_base = object method virtual to_string : unit -> t_string end;; class oo_string s0 = object inherit oo_base val mutable s : string = s0 method to_string () = (new oo_string s :> t_string) method gets () = s method append (s' : t_string) = (new oo_string (s ^ (s'#gets ())) :> t_string) method print () = print_string s; print_newline () end;; ((new oo_string "Toto" : oo_string :> oo_base)#to_string ())#print ();; class oo_int n0 = object inherit oo_base val mutable n : int = n0 method to_string () = (new oo_string (string_of_int n) :> t_string) method getn () = n method add (n' : oo_int) = new oo_int (n + (n'#getn ())) end;; class oo_list l0 = object inherit oo_base val mutable l : oo_base list = l0 method to_string () = (List.fold_left (fun s (x : oo_base) -> (s#append (x#to_string ()))#append (new oo_string "; ")) (new oo_string "[ ") l)#append (new oo_string "]") end;; ((new oo_list [ (new oo_int 16 :> oo_base) ; (new oo_int 64 :> oo_base) ])#to_string ())#print ();; (******************************************************************************) (* 3. La sempiternelle GUI ****************************************************) (******************************************************************************) (* 3.2. Votre première fenêtre ************************************************) class ['observer] subject = object (self : 'mytype) val mutable observers : 'observer list = [] method add obs = observers <- obs :: observers method notify (message : 'observer -> 'mytype -> unit) = List.iter (fun obs -> message obs self) observers end;; class ['subject] observer = object end;; class ['obs] window title0 x0 y0 = object (self) inherit ['obs] subject val title : string = title0 val mutable x : int = x0 val mutable y : int = y0 method getx = x method gety = y method move x0 y0 = x <- x0; y <- y0; self#notify (fun obs _ -> (obs#moved self self#getx self#gety)) method draw () = print_string ("Drawing window \""^title^"\" at location x,y = "); print_int x; print_string ","; print_int y; print_string "."; print_newline () end;; class ['sub] window_obs = object inherit ['sub] observer method moved (win : 'sub) (x : int) (y : int) = print_string "Moving at location x,y = "; print_int x; print_string ","; print_int y; print_string "..."; print_newline (); win#draw () end;; let w = new window "Example" 100 100;; let o = new window_obs;; w#add o;; w#move 300 150;;