Semaine 5 – Aspects impératifs, graphiques

photo en cc-by-nc-sa par Hans Watson
, par
Encore un peu de récursion terminale (des corrections). Expression à évaluer (étant donné son arbre). Aspects impératifs : unit, for et while, enregistrements avec champs mutables, références, tableaux. Mode graphique.
- (* factorielle encore ! *)
- let rec factorielle = function
- | 0 -> 1
- | n -> (factorielle (n - 1))
- * n
- ;;
- (* et maintenant on peut l'ecrire en tail recursive *)
- let factorielle n =
- let rec fact_tr n acc = match n with
- | 0 -> acc
- | n -> fact_tr (n - 1) (acc * n)
- in
- fact_tr n 1;;
- (* evaluer une expression algebrique *)
- | Plus of expr * expr
- | Mult of expr * expr
- | Fact of expr
- ;;
- let x = Mult (Plus (Nb 3, Fact (Nb 4)), Nb 5);;
- let rec eval = function
- | Nb n -> n
- | Plus (x, y) -> (eval x) + (eval y)
- | Mult (x, y) -> (eval x) * (eval y)
- | Fact x -> factorielle (eval x)
- ;;
- eval x;;
- (* tail recursion encore *)
- (* renverser une liste *)
- let rec reverse = function
- | [] -> []
- | x::xs -> (reverse xs)@[x];;
- reverse [2;3;4;5];;
- let rec concat_reverse s acc = match s with
- | [] -> acc
- | x::xs -> concat_reverse xs (x::acc)
- ;;
- let reverse s = concat_reverse s [];;
- reverse [2;3;4;5];;
- concat_reverse [3;2;1] [4;5;6];;
- (* renverser une liste version tail recursive *)
- (* fusionner deux listes triees *)
- let rec merge u v = match (u, v) with
- | ([], []) -> []
- | (s, []) -> s
- | ([], t) -> t
- | (x::s, y::t) when x < y -> x::(merge s v)
- | (x::s, y::t) -> y::(merge u t)
- ;;
- merge [1;1;2;5;6] [1;2;2;3;4;8];;
- let merge u v =
- let rec merge_tr u v acc = match (u, v) with
- | ([], []) -> reverse acc
- | (x::s, []) -> merge_tr s [] (x::acc)
- | ([], y::t) -> merge_tr [] t (y::acc)
- | (x::s, y::t) when x < y
- -> merge_tr s v (x::acc)
- | (x::s, y::t) -> merge_tr u t (y::acc)
- in
- merge_tr u v []
- ;;
- merge [1;1;2;5;6] [1;2;2;3;4;8];;
- (* aspects impératifs *)
- ();;
- (* for et while *)
- for i = 0 downto -5 do
- print_int i;
- done;
- ;;
- (* enregistrements *)
- (3, "Foo", "Bar", 14.5);;
- type etudiant = {
- };;
- let foobar =
- {numero = 3;
- prenom = "Foo"; nom = "Bar";
- note = 14.5
- };;
- let etudiant_to_note e =
- e.note
- ;;
- etudiant_to_note foobar;;
- foobar.note;;
- type accord = {
- };;
- let doM = {note= "do"; mode = "Majeur" };;
- etudiant_to_note;;
- etudiant_to_note doM;;
- let tonote e =
- e.note;;
- let a = {x = 100.; y = 200.};;
- let add a b =
- {x = a.x +. b.x;
- y = a.y +. b.y;
- };;
- (* sucre syntaxique : créer un opérateur infixe *)
- let ( +: ) = add;;
- a +: a;;
- let ( *: ) = fun lambda a -> {
- x = lambda *. a.x;
- y = lambda *. a.y;
- };;
- (0.5 *: a) +: a;;
- (* mutable *)
- type machin = {
- };;
- let a = {truc = 45; chose = 67};;
- a.truc;;
- a.truc <- 34;;
- a.truc;;
- (* a.chose <- 36;; refusé *)
- (* plutot que de faire *)
- let a = {valeur = 45};;
- a.valeur <- 34;;
- (* On a une notation pour la meme chose, plus pratique, sans declarer *)
- (* de type *)
- (* cela s'appelle les références, nos variables impératives en ocaml *)
- let a = ref 45;;
- a := 35;;
- !a;;
- !a + 3;;
- (* factorielle iterative *)
- let fact n =
- let produit = ref 1 in
- for i = 1 to n do
- produit := !produit * i;
- done;
- !produit
- ;;
- fact 4;;
- (* tableaux *)
- (1,2,3);; (* tuple *)
- [1;2;3];; (* liste *)
- let tab = [|1;2;3|];; (* tableau ! *)
- tab.(0) <- tab.(2) + 1;;
- tab;;
- Array.map
- (function x -> x + 45)
- tab;;
- (* dessiner *)
- #load "graphics.cma"
- (* open Graphics;; ou bien *)
- (* ouvrir l'affichage graphique
- /!\ noter l'espace en début de chaîne *)
- G.open_graph " 1000x800";;
- (* choisir une couleur *)
- G.set_color 0xFFCC00;;
- (* dessiner un polygone plein *)
- (function (x,y) -> (x + 500, y + 400))
- [|(4,5); (100, 56); (45,60);|]);;
- (* effacer l'écran *)
- G.clear_graph ();;
- (* ne plus synchroniser automatiquement buffer et ecran *)
- G.auto_synchronize false;;
- (* ne plus ecrire dans le buffer *)
- G.display_mode true;;
- G.remember_mode false;;
- (* dessiner la forme pleine en jaune *)
- G.set_color 0xFFCC00;;
- (function (x,y) -> (x + 500, y + 400))
- [|(4,5); (100, 56); (45,60);|]);;
- G.fill_poly forme;;
- (* dessiner dans le buffer et sur l'écran *)
- G.display_mode true;;
- G.remember_mode true;;
- (* dessiner le contour de de la forme *)
- G.set_color 0xFF00FF;;
- G.set_line_width 3;;
- G.draw_poly forme;;
- (* copier le buffer sur l'ecran *)
- G.synchronize ();; (* affiche la forme creuse *)
- (* fermer l'affichage graphique *)
- G.close_graph ();;