TD1 1 Expressions, sous-expressions et r`egles de portée 2 Fonctions

publicité
Licence 3, semestre 5, 2013–2014
Programmation Fonctionnelle
TD1
1
Expressions, sous-expressions et règles de portée
Entourer toutes les sous-expressions (et sous-sous-expressions) des expressions
suivantes. Vérifier également le respect des règles de portée. Si la déclaration est typable, donner son type et sa valeur. Chaque ligne correspond à une ligne du top-level.
1. let x = 1 in x + 1
2. let x = 3
let x = 1 in x + 1
let y = x + 2
3. let x = 1 in let y = 2 in let x = 3 in x + y
4. let x = 3
let x = 1 in let y = x + 2 in x + y
5. let x = 3
let x = let y = 4 in y + 1 in x + y
6. let x = let y = 1 in x + y in x * 2
7. let x = 1 in let y = let x = 2 in x in y + x
8. let x = if true then let y = 2 in y + 1 else 5
9. let x = if true then let tmp = 5.0 in 0.0 else tmp /. 2.0
10. let () = if c then print int 1; print int 3
11. let x = if true then print int 1; 3 else 5
2
Fonctions
Donner le type des fonctions suivantes ou expliquer pourquoi elles ne sont pas typables.
1
1. let f x = x *. 2. /. 4
2. let f x y =
let x = float (x + 3) in
Printf.printf "valeur %s : %f\n" y x
3. let f x y =
let g x y = float x +. y in
g y x
4. let f
let
let
g x
x
g
h
+
=
x = x + 1 in
x = x +. 2. in
h x
5. let f x =
let g y = y + int_of_string x in
let x = 12 in
g 4
6. let f x =
let g y = y +. float x in
let x = 12 + x in
g x
3
Programmation : drag and drop
3.1 Échauffements
Le but de cette partie est de se familiariser avec les types et les fonctions données
en annexes.
Écrire une fonction val echauffement : unit -> unit qui effectue
les étapes suivantes :
1. Lancer une fenêtre graphique de taille 300 × 300,
2. Attendre qu’une touche du clavier soit tapée,
3. Afficher le caractère de la touche et la position du curseur de la souris à ce moment là sur le terminal.
Maintenant, on va programmer une petite application pour déplacer un disque de
couleur à l’aide de la souris, selon le principe du drag and drop : on clique sur le disque
pour le sélectionner, on le déplace avec la souris tant que le bouton est pressé, puis on
le “repose” en relâchant le bouton.
2
3.2
Premier pas : la fonction push
Le premier pas consiste à détecter un clic de souris au sein du cercle. Écrire une
fonction récursive
val push : (int * int) -> unit
tel que l’appel de fonction push (x,y) effectue les étapes suivantes :
1. Attendre un clic de souris dans la fenêtre
2. Vérifier que l’on a cliqué dans le cercle de centre (x,y) sinon revenir en 1.
3. Colorier le cercle en rouge.
On utilise alors cette fonction de la manière suivante.
1. Dessiner un cercle noir de rayon 10 et placé en (100, 100).
2. Appeler la fonction push (100,100).
3. Attendre un clic de souris dans la fenêtre.
4. Quitter.
3.3 drag and drop
Pour réaliser le déplacement du cercle, écrire tout d’abord une fonction
val move : (int * int) -> (int * int) -> (int * int) ->
(int * int)
tel que l’appel move (x,y) (mx,my) (sx,sy) renvoie le couple (sx mx + x,sy - my + y).
Ensuite, écrire une fonction de déplacement
val drag : (int * int) -> (int * int) -> unit
mutuellement récursive avec push tel que l’appel drag (x,y) (mx,my) effectue les étapes suivantes :
1. Attendre que la souris soit déplacée ou le bouton relâché.
2. Rappeler push si le bouton est relâché.
3. Sinon calculer les nouvelles coordonnées du cercle à l’aide de la fonction move.
4. Retourner en 1
Enfin, modifier la fonction push de manière à ce que l’étape 3 de son algorithme
soit remplacée par un appel à la fonction drag.
3
3.4
Annexes
Ici est présenté un extrait de la bibliothèque graphics. Pour l’utiliser :
This library is implemented under the X11 windows system. Programs that use
the graphics library must be linked as follows:
ocamlc other options graphics.cma other files
or start ocaml and type
#load "graphics.cma";;.
Voici les fonctions dont vous pourrez avoir besoin :
– val open graph : string -> unit Show the graphics window or
switch the screen to graphic mode. The graphics window is cleared and the current point is set to (0, 0). The string argument is used to pass optional information
on the desired graphics mode, the graphics window size, and so on. Its interpretation is implementation-dependent. If the empty string is given, a sensible default
is selected. Example : open graph " 300x300"
– type status = {
mouse_x : int ;
X coordinate of the mouse
mouse_y : int ;
Y coordinate of the mouse
button : bool ;
true if a mouse button is pressed
keypressed : bool ;
true if a key has been pressed
key : char ;
the character for the key pressed
}
type event =
| Button_down
A mouse button is pressed
| Button_up
A mouse button is released
| Key_pressed
A key is pressed
| Mouse_motion
The mouse is moved
| Poll
Don’t wait; return immediately
To specify events to wait for.
– val wait next event : event list -> status Wait until one
of the events specified in the given event list occurs, and return the status of
4
the mouse and keyboard at that time. If Poll is given in the event list, return immediately with the current status. If the mouse cursor is outside of the
graphics window, the mouse x and mouse y fields of the event are outside the
range 0..size x()-1, 0..size y()-1. Keypresses are queued, and dequeued one by
one when the Key pressed event is specified.
– val clear graph : unit -> unit
Erase the graphics window.
– val draw circle : int -> int -> int -> unit draw circle
x y r draws a circle with center x,y and radius r. The current point is unchanged. Raise Invalid argument if r is negative.
– val fill circle : int -> int -> int -> unit Fill a circle with
the current color. The parameters are the same as for Graphics.draw circle[25.1].
– type color = int
– val red : color
– val set color : color -> unit
5
Set the current drawing color.
Téléchargement