Vous êtes sur la page 1sur 3

SESSION DE RATTRAPAGE JUILLET 2021

PROGRAMMATION FONCTIONNELLE : ELEMENTS DE CORRECTION

Exercice 1 : Questions de cours (6.5pts)


1- Considérons le programme C suivant :
int i = 0 ;
int g(int j) {
i += j;
return i;
}

a- Que désigne-t-on par transparence référentielle d’un programme ? 1pt


La transparence référentielle d’un programme est une propriété dudit
programme qui fait qu'il peut être remplacé par sa valeur de retour sans
changer le comportement du contexte d’appel.
b- Montrer que le programme précédent ne possède pas cette propriété. 1pt
Avec le programme précédent, un premier appel de g avec pour
argument 1 donne g(1) = 1, un second appel identique donne plutôt g(1)
= 2. Par conséquent g(1) ne peut pas être remplacé par 1 ; pire encore g(1)
– g(1) n’est pas nul.
c- Quel en est la raison ? A partir de cet exemple, peut on dire que le
programme précédent est un programme à effets de bord ? 0.5pt + 0.5pt
La raison c’est que le programme manipule des variables globales.
Oui, le programme précédent est un programme à effets de bords, car la
fonction g utilise et modifie des variables non locales.
d- Pourquoi dit-on que Haskell est un langage fonctionnel pur ? 1pt
Parce qu’en Haskell, toutes les fonctions sont pures ; i.e. elles ne sont pas
à effet de bords.
2- Que désigne-t-on par instanciation partielle des fonctions ? 1pt
Instancier partiellement une fonction, c’est l’utiliser en fournissant juste une
partie des arguments qu’elle attend.
3- Soit la fonction définie par square x = x * x. Proposer une réduction totale de
l’expression e = (square (3 + 4)) + (5 - 2) en utilisant uniquement des réductions
extérieures 1.5pts
e = (square (3 + 4)) + (5 - 2) = ((3 + 4) * (3 + 4)) + (5 - 2) = (7 * (3 + 4)) + (5 - 2) = (7 *
7) + (5 - 2) = 49 + (5 - 2) = 49 + 3 = 52

Exercice 2 : Types et classes de types (8.5pts)


On voudrait écrire un module Haskell pour la manipulation des figures
géométriques suivantes : les carrés, les rectangles et les cercles. Un cercle est
défini par son centre qui est de type Point et son rayon de type Float.
1- Proposer les types Carre, Rectangle et Cercle correspondants. 1.5pts
data Carre = MKCarre Float
data Rectangle = MKRect Float Float
data Point = MKPoint Float Float
data Cercle = MKCercle Point Float

NB : accepter les types polymorphes


2- Donner les types des constructeurs de données de vos différents types. 1.5pts
MKCarre :: Float -> Carre
MKRect :: Float -> Float -> Rectangle
MKPoint :: Float -> Float -> Point
MKCercle :: Point -> Float -> Cercle

3- Proposer une classe de type FigureGeometrique contenant les signatures des


fonctions surface et perimetre qui permettent d’évaluer la surface et le
périmètre des figures géométriques. 1.5pts
class FigureGeometrique a where
perimetre :: a -> Float
surface:: a -> Float
4- Créer les instances de FigureGeometrique pour les types Carre, Rectangle et
Cercle. 3pts
instance FigureGeometrique (Carre) where
perimetre (MKCarre cote) = cote * 4
surface (MKCarre cote) = cote * cote

instance FigureGeometrique (Rectangle) where


perimetre (MKRect long larg) = (long + larg) * 2
surface (MKRect long larg) = long * larg

instance FigureGeometrique (Cercle) where


perimetre (MKCercle (MKPoint x y) rayon) = pi * rayon * 2
surface (MKCercle (MKPoint x y) rayon) = pi * rayon * rayon
5- Ecrire une fonction evaluerSurfaces qui prend une liste de FigureGeometrique
en paramètre et renvoie la liste de leurs surfaces respectives. 1pt

evaluerSurfaces :: FigureGeometrique a => [a] -> [Float]


evaluerSurfaces [] = []
evaluerSurfaces (x:xs) = surface x : evaluerSurfaces xs

NB : accepter pour cette fois, les types polymorphes (voir l’exemple ci-dessous
pour le carré)
data CarreP a = MKCarreP a

class FigureGeometriqueP a where


perimetreP :: (Num b) => a b -> b
surfaceP :: (Num b) => a b -> b

instance FigureGeometriqueP (CarreP) where


perimetreP (MKCarreP cote) = cote * 4
surfaceP (MKCarreP cote) = cote * cote

evaluerSurfacesP :: (FigureGeometriqueP a, Num b) => [a b] -> [b]


evaluerSurfacesP [] = []
evaluerSurfacesP (x:xs) = surfaceP x : evaluerSurfacesP xs

Exercice 3 : Manipulation des types polymorphes (5pts)


On désire manipuler des nombres complexes en Haskell
1- Proposer un type polymorphe NombreComplexe a de donnée à cet effet 1pt
data NombreComplexe a = MKComp a a
2- Représenter le nombre complexe -5i + 12.2 à l’aide de votre type. 1pt
z1 = MKComp 12.2 -5
3- Que faut-il faire pour pouvoir comparer deux nombres complexes grâce aux
opérateurs == et /= ? 1pt
Il faudrait créer une instance de la classe Eq pour le type NombreComplexe
4- Ecrire une fonction somme qui fait la somme de deux nombres complexes.2pts
somme :: Num a => NombreComplexe a -> NombreComplexe a ->
NombreComplexe a
somme (MKComp x y) (MKComp a b) = (MKComp (x + a) (y + b))

Vous aimerez peut-être aussi