(*** Exercice 1 ***) (* Image with only load and save *) module type IMAGE_IO = sig type image = Graphics.color array array val load : string -> image val save : image -> string -> unit end;; module M:IMAGE_IO = struct type image = Graphics.color array array let load s = let img = Images.load s [] in (Graphic_image.array_of_image img);; let save i s = let grf = Graphics.make_image i in let img = Images.Rgb24(Graphic_image.image_of grf) in Images.save s None [] img;; end;; (* Image with mapping abilities *) module type IMAGE_MAP = sig include IMAGE_IO type color = Graphics.color val map : (color -> color) -> image -> image end;; module N:IMAGE_MAP = struct include M type color = Graphics.color let map f i = Array.map (fun t -> Array.map f t) i;; end;; (* Color manipulation *) module type COLOR = sig type color = Graphics.color val red : color -> color val green : color -> color val blue : color -> color end module C:COLOR = struct type color = Graphics.color let blue c = c mod 256 let green c = ((c/256) mod 256)*256 let red c = (c/65536)*65536 end module type IMAGE_COM = sig include IMAGE_IO val red_component : image -> image val blue_component : image -> image val green_component : image -> image end module P:IMAGE_COM = struct include N module C = C (* Warning : two definitions of type color *) let red_component i = map (C.red) i let blue_component i = map (C.blue) i let green_component i = map (C.green) i end (*** Exercice 2 ***) (* Set module *) module type SET = sig type 'a set val empty : unit -> 'a set val add : 'a set -> 'a -> 'a set val mem : 'a set -> 'a -> bool val union : 'a set -> 'a set -> 'a set val inter : 'a set -> 'a set -> 'a set end (* Notice that the type for 'a set is made public *) module S_FUN:SET with type 'a set = ('a -> bool) = struct type 'a set = ('a -> bool) let empty() = (fun x -> false);; let mem s x = s x;; let add s x = (fun y -> s y || y = x);; let union s1 s2 = (fun y -> s1 y || s2 y);; let inter s1 s2 = (fun y -> s1 y && s2 y);; end (* Functor with two arguments *) module MAKE_COM(C:COLOR)(I:IMAGE_MAP):IMAGE_COM = struct include I module C = C let red_component i = map (C.red) i let blue_component i = map (C.blue) i let green_component i = map (C.green) i end (* Image collection *) module type IMAGE_COLLEC = sig type image type collection val empty_collection : unit -> collection val add_image_direct : image -> collection -> collection val add_image_load : string -> collection -> collection end module MAKE_COLLEC(I:IMAGE_IO)(S:SET):IMAGE_COLLEC with type collection = I.image S.set and type image = I.image = struct type image = I.image type collection = image S.set let empty_collection = S.empty let add_image_direct i c = S.add c i let add_image_load s c = let img = I.load s in add_image_direct img c end (* Sets with removal *) module type SET_DEL = sig include SET val remove : 'a set -> 'a -> 'a set end module SR_FUN:SET_DEL with type 'a set = 'a S_FUN.set = struct include S_FUN let remove s x = (fun y -> s y && not(y = x));; end module type IMAGE_REMOVABLE_COLLEC = sig include IMAGE_COLLEC val remove_image : image -> collection -> collection end module MAKE_REMOVABLE_COLLEC(I:IMAGE_IO)(S:SET_DEL):IMAGE_REMOVABLE_COLLEC = struct include MAKE_COLLEC(I)(S) let remove_image i c = S.remove c i end (*** Exercice 3 ***) module type GRAPHIC_ELEM = sig type t type extern_t val make : extern_t -> t val draw : t -> unit val translate : int*int -> t -> t end module Disk (S : sig val radius : int end): GRAPHIC_ELEM with type extern_t = (int*int) = struct module G = Graphics let radius = S.radius type t = {x:int; y:int} type extern_t = int*int let make (x,y) = {x=x; y=y} let draw p = G.fill_circle p.x p.y radius let translate (t1,t2) {x=x; y=y} = {x=x+t1; y=y+t2} end module D = Disk(struct let radius = 4 end);; module Picture(G : GRAPHIC_ELEM) : GRAPHIC_ELEM with type extern_t = G.t list = struct type t = G.t list type extern_t = G.t list let make l = l let draw l = List.iter (G.draw) l let translate (t1,t2) l = List.map (G.translate (t1,t2)) l end module P = Picture(D);; let coord_list = [ (50,55); (60,70); (57,85); (60,100); (50,115); (65,135); (80,130) ];; let casserole = P.make (List.map (D.make) coord_list);; Graphics.open_graph "";; P.draw casserole;;