Académique Documents
Professionnel Documents
Culture Documents
U NIVERSITÉ DE D OUALA
FACULTÉ DES S CIENCES
Département de Mathématiques et
Informatique
Licence 2
Informatique
INF274
Programmation fonctionnelle
II
Timing
— Total horaire : 30h
— Cours magistral (CM) : 16h
— Travaux Dirigés (TD) : 8h
— Travaux Pratiques (TP) : 6h
— Crédits : 3
Objectifs
Ce cours s’inscrit dans la suite du cours d’introduction à la pro-
grammation fonctionnelle, vu en première année. La notion d’ap-
plication développée en Haskell y est abordée et l’accent est surtout
mis sur les structures de données, les algorithmes qui vont avec et
une petite introduction à la théorie de la programmation.
Documentation
1. Introduction to Functional Programming using Haskell. Ri-
chard Bird, Prentice Hall ; 2 edition (May 9, 1998), 448 pages.
2. Paul Hudak and Joseph H. Fasel. 1992. A gentle introduction
to Haskell. SIGPLAN Not. 27, 5 (May 1992), 1–52.
DOI :https ://doi.org/10.1145/130697.130698.
2
3
1 Les Listes 6
1.1 Notations . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2 Opération sur les listes . . . . . . . . . . . . . . . . . . 6
1.2.1 Ajout d’un élément . . . . . . . . . . . . . . . . . 6
1.2.2 Tête et queue . . . . . . . . . . . . . . . . . . . . 6
1.2.3 Concaténation . . . . . . . . . . . . . . . . . . . 7
1.2.4 Fusion d’un ensemble listes . . . . . . . . . . . 7
1.2.5 Inverser une liste . . . . . . . . . . . . . . . . . . 8
1.2.6 Longueur d’une liste . . . . . . . . . . . . . . . . 8
1.2.7 Indexation . . . . . . . . . . . . . . . . . . . . . . 8
1.2.8 Foncteur pour une liste . . . . . . . . . . . . . . 9
1.2.9 Filtrage d’une liste par prédicat . . . . . . . . . 9
1.3 Liste en compréhension . . . . . . . . . . . . . . . . . . 10
1.4 La fonction Zip . . . . . . . . . . . . . . . . . . . . . . . 10
1.5 Les folds . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
4
TABLE DES MATIÈRES 5
Les Listes
1.1 Notations
Une liste est une collection d’éléments de même type ; c’est une
structure de donnée se décrivant de manière récursive. Une liste se
présente en Haskell entre crochets, les éléments étant séparés par
des virgules. La liste vide est dénotée par [ ] ; si les éléments d’une
liste sont de type a, alors la liste aura pour type [a]. Exemple :
[1, 2, 3] :: [Int]
[0 h0 ,0 a0 ,0 l0 ,0 l0 ,0 o0 ] :: [Char]
[[1, 2], [3]] :: [[Int]]
[(+), (∗)] :: [Int → Int → Int]
6
CHAPITRE 1. LES LISTES 7
1.2.3 Concaténation
La concaténation est l’opération permettant d’obtenir une liste
résultante, à partir de deux listes. Elle définie par l’opérateur (++) ::
[a] → [a] → [a].
[1, 2, 3] + +[4, 5] = 1 : ([2, 3] + +[4, 5])
= 1 : (2 : ([3] + +[4, 5]))
= 1 : (2 : ([3] + +[4, 5]))
= 1 : (2 : (3 : ([] + +[4, 5])))
= 1 : (2 : (3 : ([4, 5])))
= 1 : 2 : 3 : [4, 5]
Sa définition formelle est
concat : : [[a]]→[a]
concat [] = []
concat (xs:xss) = xs ++ concat xss
CHAPITRE 1. LES LISTES 8
concat[[1, 2], [], [3, 2, 1]] = concat ([1, 2] : [[], [3, 2, 1]])
= [1, 2] + +concat ([] : [[3, 2, 1]])
= [1, 2] + +[] + +concat ([3, 2, 1] : [])
= [1, 2] + +[] + +[3, 2, 1] + +concat []
= [1, 2] + +[] + +[3, 2, 1] + +[]
= [1, 2, 3, 2, 1] déf inition de + +
reverse::[a] → [a]
reverse [] = []
reverse (x:xs) = reverse xs ++ [x]
length::[a] → Int
length [] = 0
length (x:xs) = 1 + length xs
1.2.7 Indexation
Les éléments d’une liste peuvent être indexés par des entiers
correspondant à leur positions dans la liste (dans un syntaxe proche
de celle des tableaux dans les langages comme C, pascal, ...). Il
devient de ce fait possible d’accéder à un élément à une position
donnée par l’opérateur d’indexation ”!!”. Ainsi
CHAPITRE 1. LES LISTES 9
[1, 2, 3, 4]!!0 = 1
[1, 2, 3, 4]!!3 = 3
Exercices 4.1 :
1. Écrire la fonction even :: Int → Bool qui dit si un nombre
est pair ou pas.
2. Évaluer les expressions suivantes en montrant tous les dé-
tails :
(a) reverse [1,2,3,4]
(b) [1,2,3,4] ! !2
(c) map square [1,2,3,4]
(d) filter even [1,2,3,4,10,17,19,32]
[x ∗ x | x ← [1..5], odd x]
Une telle expression, équivaut à la liste [1, 9, 25], puisque les élé-
ments de liste sont les carrés des nombres impairs compris entre 1
et 5.
Programmation modulaire et
opérations d’entrées/sorties
11
CHAPITRE 2. PROGRAMMATION MODULAIRE ET OPÉRATIONS D’ENTRÉES/SORTIE
import N om_module
CHAPITRE 2. PROGRAMMATION MODULAIRE ET OPÉRATIONS D’ENTRÉES/SORTIE
do putStr ”Hello”
putStr ” ”
putStr ”World”
putStr ”\n”
do test ← getLine
return text
main::IO()
main = do c ← getChar
putChar c
getChar :: IO Char
getLine :: IO String
getContents :: IO String
main = do
putStrLn ”Entrer un nombre entier”
input1 ← getLine
let a = read input1::Int
putStrLn ”Entrer un nombre entier”
input2 ← getLine
let b = read input2::Int
print(pgcd a b)
Chapitre 3
3.1 Généralités
Un type abstrait de données (ou TAD ou Abstract DataType),
est un type de donnée dont chacune des valeurs est une donnée
d’un autre type, enveloppée dans un constructeur de type. Toutes
les données enveloppées sont les arguments du constructeur.
Le constructeur ici n’est pas une fonction susceptible d’être éva-
luée, la seule manière d’opérer sur les données, est d’appliquer le
mécanisme de filtrage de motifs (pattern matching), pour enlever le
constructeur.
18
CHAPITRE 3. TYPES DE DONNÉES ALGÉBRIQUES 19
Soit à évaluer
len Cons 1 (Cons 2 (Cons 3 N il))) = 1 + len Cons 2 (Cons 3 N il))
= 1 + 1 + len Cons 3 N il
= 1 + 1 + 1 + len N il
= 1+1+1+0
= 3
Exercices
1. Écrire la fonction conc :: List a → List a → List a équivalente
à (++), qui concatène deux listes.
2. Écrire la fonction rev :: List a → List a équivalente à reverse,
qui inverse l’ordre des éléments de la liste.
3. Écrire les fonctions head et tail associées.
4. Proposer un foncteur map pour le type List a.
Fiche de TD/TP (N°1)
23
CHAPITRE 3. TYPES DE DONNÉES ALGÉBRIQUES 24
Exercice 4 : Polynômes
Un polynôme d’ordre n s’exprime sous la forme an xn + an−1 xn−1 +
. . . + a1 x + a0 avec ai ∈ N, x ∈ R étant la variable.
En supposant que les coefficients du polynôme sont représentés
par une liste simplement chaînée telle, que l’élément ai se trouve à
la position n − i ; exemple, le polynôme 4x3 + 2x2 + 1 sera représenté
par la liste [4, 2, 0, 1]. On voudrait mettre en œuvre une bibliothèque
de fonctions pour manipuler les polynômes.
1. Définir le type abstrait P oly a b équivalent à la liste ci-dessus,
avec a les types génériques des coefficients et b type géné-
rique des variables.
CHAPITRE 3. TYPES DE DONNÉES ALGÉBRIQUES 25
4.1.1 Représentation
Structure de donnée
26
CHAPITRE 4. LES STRUCTURES D’ARBRES 27
Foncteur associé
Exercice
Écrire une fonction permettant de compter les nœuds internes
d’un Btree.
avec
join :: Stree a → Stree a → Stree a
join Null yt = yt
join (Fork ut x vt) yt = Fork ut x (join vt yt)
Exercice :
1. Définir le foncteur associé à un Stree
2. Définir la fonction empty :: Stree a → Bool qui indique s’il
n’y a aucun élément dans l’arbre.
Fiche de TD/TP (N°2)
Exercice 1 : Le Quadtree
Un quadtree est une structure de données de type arbre dans
laquelle chaque nœud a quatre fils. Les quadtrees sont le plus sou-
vent utilisés pour partitionner un espace bidimensionnel en le sub-
divisant récursivement en quatre nœuds.
Le quadtree peut être défini en haskell par :
data QuadTree a = Leaf a
| Node (QuadTree a)(QuadTree a)(QuadTree a)(QuadTree a)
deriving(Show)
1. Proposer un exemple de terme correspondant à cette défini-
tion.
2. Ecrire la fonction flattern correspondante au quadtree.
3. Ecrire les fonctions size et height correspondantes.
4. Ecrire la fonction map associée.
32
CHAPITRE 4. LES STRUCTURES D’ARBRES 33
On définit :
data Couleur = Blanc | Noir deriving(Show)
1. Proposer une représentation d’une image dans ce contexte ;
2. Écrire une fonction inverse qui prend un quadtree qt repré-
sentant une image i et renvoie un quadtree représentant
l’image i0 obtenue à partir de i en échangeant Noir et Blanc.
3. Écrire une fonction rotate qui prend un quadtree qt représen-
tant une image i et renvoie un quadtree représentant l’image
i tournée d’un quart de tour vers la gauche.
4. Considérons le type
data Bit = Zero | Un deriving(Show)
On souhaite pouvoir transformer un Quadtree Color en un QuadT ree Bit ;
sachant que Blanc se code Zero et Noir se code Un, écrire la fonc-
tion code qui fait usage de la fonction map de QuadTree pour réaliser
cela.
Le main
1. Proposer une fonction main permettant de lire la description
d’une image, fournie par l’utilisateur puis, afficher successi-
vement l’inverse, la rotation et le codage de cette image.
2. Générer l’exécutable haskell par la commande :
$ ghc -o <nom executable> <nom fichier>.hs
CHAPITRE 4. LES STRUCTURES D’ARBRES 34
Exercice 3 : La génétique
L’ADN est un polymère composé uniquement de quatre nucléo-
tides : l’adénine, la thymine, la guanine et la cytosine, qui consti-
tuent donc les "lettres" de "l’alphabet" génétique. L’ADN est consti-
tué de deux fibres constituées à partir de ces quatre nucléotides.
Ces deux fibres sont "complémentaires" : chaque nucléotide d’une
fibre est lié à un autre sur l’autre fibre, sachant que l’Adénine (A)
s’associe avec la Thymine (T) et la Guanine (G) avec la Cytosine (C).
On va créer des fonctions pour représenter et manipuler ces
fibres : une fibre sera constituée d’une liste de nucléotides. Pour
certaines de ces fonctions, il faudra peut-être décomposer le pro-
blème en plusieurs parties.
1. Définir les types N ucleotide et F ibre
2. f ibreV ide : qui teste si une fibre est vide ou non.
3. complement : qui prend un nucléotide et renvoie son complé-
ment ;
4. dupliquer qui renvoie le complémentaire d’une fibre passée
en paramètre. Par exemple, dupliquer [ ‘A‘,‘T‘,‘T‘,‘C‘] renvoie [
‘T‘,‘A‘, ‘A‘,‘G‘ ].
5. comparer qui renvoie vrai si 2 fibres sont complémentaires.