programmation fonctionnelle avancee´conchon/pfa/manpfa1.pdf · programmation fonctionnelle...

226
Programmation fonctionnelle avanc ´ ee Notes de cours Remise ` a niveau 5 septembre 2017 Sylvain Conchon [email protected] 1/103

Upload: phungkhuong

Post on 11-Sep-2018

249 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Programmation fonctionnelleavancee

Notes de cours

Remise a niveau

5 septembre 2017

Sylvain Conchon

[email protected]

1/103 1

Page 2: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Structure du cours

Le cours est a la fois :

I Une introduction a la programmation fonctionnelleI Une initiation au langage OCaml

2/103 2

Page 3: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Un livre qui peut vous aider (Amazon, FNAC, etc.)

http://programmer-avec-ocaml.lri.fr/

978

2212

1367

84

3/103 3

Page 4: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Environnements de travail

4/103 4

Page 5: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le langage OCaml

http://caml.inria.fr

I langage developpe a l’INRIA (Institut National de Rechercheen Informatique et en Automatique)

I disponible sur de nombreuses architectures (Linux, Windows,Mac OS X etc.)

5/103 5

Page 6: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Les outils

Nous allons utiliser les outils suivants en TP :

I un terminal unixI un editeur de texte : emacsI un interpreteur de commandes OCaml : ocamlI un compilateur pour OCaml : ocamlc

6/103 6

Page 7: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Demonstration

Le premier programme :

afficher Hello world! a l’ecran

7/103 7

Page 8: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

L’interpreteur : lancement

Tres pratique pour ecrire de petits programmes ou connaıtre lavaleur (ou le type) d’une expression

Pour cela, dans la terminal je tape simplement ocaml

> ocaml

OCaml version 4.01.0

#

Le symbole # est l’invite de commande de l’interpreteur : il vousinvite a ecrire une expression OCaml

8/103 8

Page 9: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

L’interpreteur : evaluation d’une expression

L’evaluation d’une expression se fait en trois temps

> ocaml

OCaml version 4.01.0

#

1 + 2 ;;

- : int = 3

#

1. Je saisie l’expression et j’indique que j’ai termine en tapant ;;

2. L’interpreteur evalue mon expression

3. Puis il affiche son type et sa valeur

9/103 9

Page 10: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

L’interpreteur : evaluation d’une expression

L’evaluation d’une expression se fait en trois temps

> ocaml

OCaml version 4.01.0

# 1 + 2 ;;

- : int = 3

#

1. Je saisie l’expression et j’indique que j’ai termine en tapant ;;

2. L’interpreteur evalue mon expression

3. Puis il affiche son type et sa valeur

9/103 9

Page 11: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

L’interpreteur : evaluation d’une expression

L’evaluation d’une expression se fait en trois temps

> ocaml

OCaml version 4.01.0

# 1 + 2 ;;

- : int = 3

#

1. Je saisie l’expression et j’indique que j’ai termine en tapant ;;

2. L’interpreteur evalue mon expression

3. Puis il affiche son type et sa valeur

9/103 9

Page 12: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

L’interpreteur : evaluation d’une expression

L’evaluation d’une expression se fait en trois temps

> ocaml

OCaml version 4.01.0

# 1 + 2 ;;

- : int = 3

#

1. Je saisie l’expression et j’indique que j’ai termine en tapant ;;

2. L’interpreteur evalue mon expression

3. Puis il affiche son type et sa valeur

9/103 9

Page 13: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

L’interpreteur : evaluation d’une expression

L’evaluation d’une expression se fait en trois temps

> ocaml

OCaml version 4.01.0

# 1 + 2 ;;

- : int = 3

#

1. Je saisie l’expression et j’indique que j’ai termine en tapant ;;

2. L’interpreteur evalue mon expression

3. Puis il affiche son type et sa valeur

9/103 9

Page 14: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le compilateur : edition, compilation, execution

L’ecriture de (gros) programmes necessite un editeur et uncompilateur

Le cycle d’utilisation du compilateur est egalement en trois temps

1. J’ecris mon programme hello.ml a l’aide d’emacs

2. Dans le terminal, je compile

> ocamlc -o hello hello.ml

>

3. J’execute mon programme

> ./hello

Hello wolrd!

10/103 10

Page 15: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le compilateur : edition, compilation, execution

L’ecriture de (gros) programmes necessite un editeur et uncompilateur

Le cycle d’utilisation du compilateur est egalement en trois temps

1. J’ecris mon programme hello.ml a l’aide d’emacs

2. Dans le terminal, je compile

> ocamlc -o hello hello.ml

>

3. J’execute mon programme

> ./hello

Hello wolrd!

10/103 10

Page 16: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le compilateur : edition, compilation, execution

L’ecriture de (gros) programmes necessite un editeur et uncompilateur

Le cycle d’utilisation du compilateur est egalement en trois temps

1. J’ecris mon programme hello.ml a l’aide d’emacs

2. Dans le terminal, je compile

> ocamlc -o hello hello.ml

>

3. J’execute mon programme

> ./hello

Hello wolrd!

10/103 10

Page 17: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le compilateur : edition, compilation, execution

L’ecriture de (gros) programmes necessite un editeur et uncompilateur

Le cycle d’utilisation du compilateur est egalement en trois temps

1. J’ecris mon programme hello.ml a l’aide d’emacs

2. Dans le terminal, je compile

> ocamlc -o hello hello.ml

>

3. J’execute mon programme

> ./hello

Hello wolrd!

10/103 10

Page 18: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Programme 1 : Annees bissextiles

Notions introduites :

I forme generale d’un programmeI types de base (int, bool, string, unit)I construction let

I appel de fonctionI fonction d’affichage Printf.printf

11/103 11

Page 19: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

La forme des programmes Ocaml

Un programme OCaml est simplement :

I une suite de declarations (let) ou d’expressions a evaluer(de haut en bas)

I la fin d’une declaration ou d’une expression est specifiee pardeux points virgules ;;

Il n’y a donc pas de point d’entree particulier (fonctionprincipale par ex.) comme dans d’autres langages.

12/103 12

Page 20: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Types et expressions elementaires

Expressions de type int : les entiers

# 4 + 1 - 2 * 2 ;;

- : int = 1

# 5 / 2 ;;

- : int = 2

# 1 000 005 mod 2 ;;

- : int = 1

# max int + 1 ;;

- : int = -1073741824

I int represente les entiers compris entre −230 et 230 − 1 (surune machine 32 bits)

I operations sur ce type : +, -, *, / (division entiere), mod (restede la division) etc.

13/103 13

Page 21: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Types et expressions elementaires

Expressions de type bool : les valeurs booleennes

# false || true ;;

- : bool = true

# 3 <= 1 ;;

- : bool = false

# not (0=2) && 1>=3 ;;

- : bool = false

# if 2<0 then 2.0 else (4.6 *. 1.2) ;;

- : float = 5.52

I les constantes true (vrai) et false (faux)I les operations sur ce type not (non), && (et) et || (ou)I les operateurs de comparaison (=, <, >, <=, >=) retournent des

valeurs booleennesI dans une conditionnelle de la forme

if exp1 then exp2 else exp3l’expression exp1 doit etre de type bool.

14/103 14

Page 22: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Types et expressions elementaires

Expressions de type char : les caracteres

# ’a’ ;;

- : char = ’a’

# int of char ’a’ ;;

- : int = 97

# char of int 100 ;;

- : char = ’d’

I les caracteres sont encadres par deux apostrophes ’

I la fonction int of char renvoie le code ASCII d’un caractere(et inversement pour la fonction char of int).

15/103 15

Page 23: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Types et expressions elementaires

Expressions de type string : les chaınes de caracteres

# "hello" ;;

- : string = "hello"

# "" ;;

- : string = ""

# "bon" ^ "jour" ;;

- : string = "bonjour"

# "hello".[1] ;;

- : char = ’e’ # string of int 123 ;;

- : string = "123"

I ces valeurs sont encadrees par deux guillemets "I l’operateur ^ concatene des chaınesI l’operation .[i] accede au ie caractere d’une chaıne (le

premier caractere est a l’indice 0)I des fonctions de conversions permettent de convertir des

valeurs de types de base en chaınes (et inversement)16/103 16

Page 24: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le type unit

# () ;;

- : unit = ()

# Print.printf "bonjour\n" ;;bonjour

- : unit = ()

I unit represente les expressions qui font uniquement deseffets de bord

I une seule valeur a ce type, elle est notee ()

I c’est l’equivalent du type void en C

17/103 17

Page 25: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Les variables globales

# let x = 3 ;;

val x : int = 3

I le type est infere automatiquement par le compilateurI le contenu d’une variable n’est pas modifiableI la portee est limitee aux declarations suivantes

# let y = 5 + x ;;

val y : int = 8

# let z = 10 + z ;;

Error: Unbound value z

I La liaison est statique : la redefinition ne change pas la valeurdes expressions precedentes

# let x = 10 ;;

val x : int = 10

# y ;;

- : int = 8

18/103 18

Page 26: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Appel de fonction

L’appel d’une fonction toto avec un argument v se notesimplement :

toto v

il n’y a donc pas de parentheses

Si la fonction toto a plusieurs arguments, par exemple troisarguments, on note simplement :

toto v1 v2 v3

19/103 19

Page 27: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

La fonction Printf.printf

(Il s’agit d’une fonction tres connues des programmeurs C)

Printf.printf prend comme premier argument une chaıne deformatage qui contient le message a ecrire

Ce message peut contenir des codes de format (commencant par%) qui indiquent qu’un argument est attendu a cet endroit

Selon le code de format, le type de l’argument est :

%d un entier%c un caractere%f un flottant%s une chaıne de caracteres

La fonction Print.printf attend donc autant d’arguments quenecessaire pour construire le message a afficher

20/103 20

Page 28: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Programme 2 : Methode de Monte-Carlo

Notions introduites :

I nombres flottants (type float)I variables locales (construction let-in)I bibliotheque de nombres aleatoires Random

I acces aux arguments d’un programme (Sys.argv)I declaration de fonctionsI fonctions recursivesI fonctions a plusieurs arguments

21/103 21

Page 29: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Calcul de π par la methode de Monte-Carlo

I soit un carre de cote 1 et le quart de cercle de rayon 1 inscritdans ce carre (l’aire de ce cercle est π/4)

I si l’on choisit au hasard un point du carre, la probabilite qu’ilsoit dans le quart de cercle est donc egalement de π/4

I en tirant au hasard un grand nombre n de points dans lecarre, si p est le nombre de points a l’interieur du cercle, alors4× p/n donne une bonne approximation de π

22/103 22

Page 30: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le type float

Expressions de type float : les nombres a virgule flottante

# 4.3e4 +. 1.2 *. -2.3 ;;

- : float = 42997.24

# 5. /. 2. ;;

- : float = 2.5

# 1. /. 0. ;;

- : float = infinity

# 0. /. 0. ;;

- : float = nan

I les types int et float sont disjointsI operations sur ce type : +. -. *. /. sqrt cos etc.I on passe d’un entier a un flottant a l’aide de la fonction

float of int et inversement avec truncate

23/103 23

Page 31: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Les variables locales

# let x = 3 in x + 1;;

- : int = 4

I la portee est limitee a l’expression qui suit le in

# x + 2;;

Error: Unbound value x

I le nom de la variable locale masque toute declarationanterieure de meme nom

# let y = 2;;

val y : int = 2

# let y = 100.5 in (truncate y) + 1;;

- : int = 101

# y + 3;;

- : int = 5

24/103 24

Page 32: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

La bibliotheque Random

Cette bibliotheque contient plusieurs fonctions pour generer desnombres aleatoires

Random.float n renvoie, de maniere aleatoire, un nombre flottantentre 0 et n (inclus) (si n est negatif, le resultat est negatif ou 0)

Il existe d’autres fonctions comme Random.int (pour generer desentiers), Random.bool, etc.

Il faut appeler la fonction Random.self init () pour initialiser legenerateur (sans quoi on obtient toujours la meme sequence pourchaque execution)

25/103 25

Page 33: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Les arguments d’un programme

L’acces aux arguments d’un programme (passes sur la ligne decommande dans le terminal) se fait a l’aide de la notation

Sys.argv.(i)

ou i est un entier tel que :

O le nom du programme execute1 le premier argument2 le deuxieme argument. . .

Sys.argv.(i) est une chaıne de caracteres

Ainsi, si je tape dans le terminal

> ./approx_pi 100

Sys.argv.(0) vaut "./approx", et Sys.argv.(1) vaut "100"26/103 26

Page 34: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions

# let f x = x + 2;;

val f : int -> int = <fun>

# f 4;;

- : int = 6

I les types, des arguments et du resultat, sont inferesI la regle de portee du nom de la fonction est identique a celle

des constantes (globales ou locales)

# let h x = x / 2 in h 6;;

- : int = 3

# h 4;;

Error : Unbound value h

# let g x = x || g (not x);;

Error : Unbound value g

27/103 27

Page 35: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions a plusieurs arguments

# let f x y z =

if x then y + 1 else z - 1;;

val f : bool -> int -> int -> int = <fun>

# f true 2 3;;

- : int = 3

I les parametres ne sont pas entre parentheses, ni dans lesdeclarations, ni dans les applications de fonctions

28/103 28

Page 36: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions recursives

# let rec fact x =

if x <= 0 then 1

else x * fact (x - 1);;

val fact : int -> int = <fun>

# fact 4;;

- : int = 24

I l’ajout du mot-cle rec change la portee de l’identificateur : ilest alors accessible dans la definition de la fonction

29/103 29

Page 37: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Programme 3 : Dessin d’une cardioıde

Notions introduites :

I bibliotheque Graphics

I Sequence d’expressions

30/103 30

Page 38: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Definition d’une cardioıde

{x(θ) = a (1− sin(θ)) cos(θ)y(θ) = a (1− sin(θ)) sin(θ)

31/103 31

Page 39: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

La bibliotheque Graphics

I ajouter le fichier graphics.cmxa dans la commande decompilation (ocamlopt ... graphics.cmxa ...)

I la directive open Graphics permet d’acceder directementaux fonctions de la bibliotheque Graphics

I open graph " 300x200" ouvre une fenetre graphique de300 pixels de large et 200 de haut

0 axe des x0

axe des y

x

y •

299

199

32/103 32

Page 40: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Quelques fonctions de Graphics

I plot x y affiche un pixel en (x, y) dans la couleur couranteI rgb r v b renvoie une couleur calculee a partir de

composantes rouge, vert et bleu (entiers entre 0 et 255) ; lescouleurs predefinies : white, black, blue, green etc.

I set color c fixe la couleur courante a la valeur cI let st = wait next event [Button down] attend un clic

de souris ; les coordonnees sont st.mouse x et st.mouse y

33/103 33

Page 41: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Sequences

Une sequence d’expressions permet d’evaluer des expressions lesunes apres les autres

# let x = Print.printf "bonjour\n"; 5 ;;

bonjour

val x : int = 5

I l’operateur de sequence est le point virgule ;I c’est un operateur binaire

Etant donnee une sequence d’expressions e1;e2;· · · ;en

I toutes les expressions e1, . . . , en−1 ne font que des effets debord

I la valeur et le type de la sequence sont ceux de la derniereexpression en

34/103 34

Page 42: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Programme 4 : La fractale de Mandelbrot

Notion introduite :

I fonctions locales

35/103 35

Page 43: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

L’ensemble de Mandelbrot

Ensemble des points (a, b) du plan pour lesquels aucune des deuxsuites recurrentes suivantes ne tend vers l’infini (en valeurabsolue)

x0 = 0y0 = 0xn+1 = x2n − y2n + ayn+1 = 2xnyn + b

I pas de methode exacte pour determiner cette conditionI on peut demontrer que l’une de ces suites tend vers l’infini

des que x2n + y2n > 4

I les points sont dans le cercle de rayon 2 centre en (0, 0)

On dessine une approximation : ensemble des points (a, b) pourlesquels x2n + y2n ≤ 4 pour les k premieres valeurs de ces suites

36/103 36

Page 44: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

les fonctions locales

Une declaration de fonction peut etre locale a une expression et oulocale a la declaration d’une autre fonction

Ainsi, le programme suivant :

let boucle n =

let rec blc_rec i =

Printf.printf "%d " i;

if i<n then blc_rec (i+1)

in

blc_rec 0;;

let carre x = x * x in boucle (carre 3);;

affiche 0 1 2 3 4 5 6 7 8 9

37/103 37

Page 45: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Definitions recursives

Une fonction est recursive si elle fait appel a elle meme dans sapropre definition

Par exemple, la fonction factorielle n! peut etre definie de maniererecursive, pour tout entier n, par les deux equations suivantes

0! = 1n! = n× (n− 1)!

38/103 38

Page 46: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions recursives en OCAML

La definition d’une fonction recursive est introduite par l’adjonctiondu mot cle rec au mot cle let

let rec fact n =

if n=0 then 1 else n * fact (n-1)

;;

39/103 39

Page 47: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Pourquoi ce mot cle rec?

La regle de portee du let

let f x = x + 1

let f y = if y=0 then f 2 else 4+y

40/103 40

Page 48: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Pourquoi ce mot cle rec?

La regle de portee du let

let f x = x + 1

let rec f y = if y=0 then f 2 else 4+y

40/103 40

Page 49: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Definitions par cas

Analyse par cas d’une valeur avec la construction match–with

let rec fact n =

match n with

| 0 -> 1

| _ -> n * fact (n-1)

;;

Ceci permet de se rapprocher encore plus de la definitionmathematique

41/103 41

Page 50: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recursivite double

Recursivite double : plusieurs appels recursifs peuvent apparaıtredans la definition

let rec fibonacci n =

match n with

| 0 -> 0

| 1 -> 1

| _ -> fibonacci (n-1) + fibonacci (n-2)

;;

42/103 42

Page 51: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recursivite double

Recursivite double : plusieurs appels recursifs peuvent apparaıtredans la definition

let rec fibonacci n =

match n with

| 0 -> 0

| 1 -> 1

| _ -> fibonacci (n-1) + fibonacci (n-2)

;;

42/103 42

Page 52: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recursivite mutuelle (1/2)

Recursivite mutuelle : une fonction f peut faire reference a unefonction g qui elle-meme fait reference a f

Dans un fichier pair.ml :

let rec pair n = (n = 0) || impair (n-1) ;;

let rec impair n = (n <> 0) && pair (n-1) ;;

compilation

> ocamlc -o pair pair.ml

File "pair.ml", line 1, characters 28-34:

Unbound value impair

43/103 43

Page 53: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recursivite mutuelle (1/2)

Recursivite mutuelle : une fonction f peut faire reference a unefonction g qui elle-meme fait reference a f

Dans un fichier pair.ml :

let rec pair n = (n = 0) || impair (n-1) ;;

let rec impair n = (n <> 0) && pair (n-1) ;;

compilation

> ocamlc -o pair pair.ml

File "pair.ml", line 1, characters 28-34:

Unbound value impair

43/103 43

Page 54: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recursivite mutuelle (2/2)

Pour definir deux fonctions f et g mutuellement recursives onutilise la construction let rec f = e1 and g = e2

let rec pair n = (n = 0) || impair (n-1)

and impair n = (n <> 0) && pair (n-1)

;;

44/103 44

Page 55: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Representation de donnees structurees

I les types de base (int, float, etc.) sont insuffisants pourrepresenter des donnees structurees (dates, matrices etc.)

I des codages existent, mais ils ne sont pas naturels (et parfoisaussi tres inefficaces)

dans ce cours nous allons etudier trois structures de donnees (etleurs operations associees)

1. les produits (n-uplets)

2. les produits nommes (enregistrements)

3. les sommes (constructeurs)

45/103 45

Page 56: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Les Types Produits

46/103 46

Page 57: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le produit cartesien

La structure de donnees la plus simple pour former des valeurscomplexes est la paire (ou produit cartesien)

# (1, 2) ;;

- : int * int = (1,2)

Les composantes des paires peuvent etre de types differents

# (’a’, 2.7) ;;

- : char * float = (’a’,2.7)

47/103 47

Page 58: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le produit cartesien

La structure de donnees la plus simple pour former des valeurscomplexes est la paire (ou produit cartesien)

# (1, 2) ;;

- : int * int = (1,2)

Les composantes des paires peuvent etre de types differents

# (’a’, 2.7) ;;

- : char * float = (’a’,2.7)

47/103 47

Page 59: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le produit cartesien

La structure de donnees la plus simple pour former des valeurscomplexes est la paire (ou produit cartesien)

# (1, 2) ;;

- : int * int = (1,2)

Les composantes des paires peuvent etre de types differents

# (’a’, 2.7) ;;

- : char * float = (’a’,2.7)

47/103 47

Page 60: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le produit cartesien

La structure de donnees la plus simple pour former des valeurscomplexes est la paire (ou produit cartesien)

# (1, 2) ;;

- : int * int = (1,2)

Les composantes des paires peuvent etre de types differents

# (’a’, 2.7) ;;

- : char * float = (’a’,2.7)

47/103 47

Page 61: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le produit cartesien

La structure de donnees la plus simple pour former des valeurscomplexes est la paire (ou produit cartesien)

# (1, 2) ;;

- : int * int = (1,2)

Les composantes des paires peuvent etre de types differents

# (’a’, 2.7) ;;

- : char * float = (’a’,2.7)

47/103 47

Page 62: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le produit cartesien

La structure de donnees la plus simple pour former des valeurscomplexes est la paire (ou produit cartesien)

# (1, 2) ;;

- : int * int = (1,2)

Les composantes des paires peuvent etre de types differents

# (’a’, 2.7) ;;

- : char * float = (’a’,2.7)

47/103 47

Page 63: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acceder aux composantes d’une paire

Les fonctions fst et snd permettent respectivement d’acceder a lapremiere et la deuxieme composante d’une paire

# snd (1,2);;

- : int = 2

# fst ((1,2.5),’a’);;

- : int * float = (1,2.5)

# let p = (1,2) in (snd p, fst p);;

- : int * int = (2,1)

48/103 48

Page 64: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acceder aux composantes d’une paire

Les fonctions fst et snd permettent respectivement d’acceder a lapremiere et la deuxieme composante d’une paire

# snd (1,2);;

- : int = 2

# fst ((1,2.5),’a’);;

- : int * float = (1,2.5)

# let p = (1,2) in (snd p, fst p);;

- : int * int = (2,1)

48/103 48

Page 65: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acceder aux composantes d’une paire

Les fonctions fst et snd permettent respectivement d’acceder a lapremiere et la deuxieme composante d’une paire

# snd (1,2);;

- : int = 2

# fst ((1,2.5),’a’);;

- : int * float = (1,2.5)

# let p = (1,2) in (snd p, fst p);;

- : int * int = (2,1)

48/103 48

Page 66: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acceder aux composantes d’une paire

Les fonctions fst et snd permettent respectivement d’acceder a lapremiere et la deuxieme composante d’une paire

# snd (1,2);;

- : int = 2

# fst ((1,2.5),’a’);;

- : int * float = (1,2.5)

# let p = (1,2) in (snd p, fst p);;

- : int * int = (2,1)

48/103 48

Page 67: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acceder aux composantes d’une paire

Les fonctions fst et snd permettent respectivement d’acceder a lapremiere et la deuxieme composante d’une paire

# snd (1,2);;

- : int = 2

# fst ((1,2.5),’a’);;

- : int * float = (1,2.5)

# let p = (1,2) in (snd p, fst p);;

- : int * int = (2,1)

48/103 48

Page 68: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acceder aux composantes d’une paire

Les fonctions fst et snd permettent respectivement d’acceder a lapremiere et la deuxieme composante d’une paire

# snd (1,2);;

- : int = 2

# fst ((1,2.5),’a’);;

- : int * float = (1,2.5)

# let p = (1,2) in (snd p, fst p);;

- : int * int = (2,1)

48/103 48

Page 69: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acceder aux composantes d’une paire

Les fonctions fst et snd permettent respectivement d’acceder a lapremiere et la deuxieme composante d’une paire

# snd (1,2);;

- : int = 2

# fst ((1,2.5),’a’);;

- : int * float = (1,2.5)

# let p = (1,2) in (snd p, fst p);;

- : int * int = (2,1)

48/103 48

Page 70: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

n-uplets

Le produit cartesien (binaire) se generalise facilement afin deregrouper les valeurs en n-uplets

# (2+3,false||true,"bonjour");;

- : int * bool * string = (5,true,"bonjour")

Les n-uplets et les paires peuvent se melanger

# (’a’,1.2,(true,0));;

- : char * float * (bool * int) = (’a’,1.2,(true,0))

49/103 49

Page 71: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

n-uplets

Le produit cartesien (binaire) se generalise facilement afin deregrouper les valeurs en n-uplets

# (2+3,false||true,"bonjour");;

- : int * bool * string = (5,true,"bonjour")

Les n-uplets et les paires peuvent se melanger

# (’a’,1.2,(true,0));;

- : char * float * (bool * int) = (’a’,1.2,(true,0))

49/103 49

Page 72: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

n-uplets

Le produit cartesien (binaire) se generalise facilement afin deregrouper les valeurs en n-uplets

# (2+3,false||true,"bonjour");;

- : int * bool * string = (5,true,"bonjour")

Les n-uplets et les paires peuvent se melanger

# (’a’,1.2,(true,0));;

- : char * float * (bool * int) = (’a’,1.2,(true,0))

49/103 49

Page 73: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

n-uplets

Le produit cartesien (binaire) se generalise facilement afin deregrouper les valeurs en n-uplets

# (2+3,false||true,"bonjour");;

- : int * bool * string = (5,true,"bonjour")

Les n-uplets et les paires peuvent se melanger

# (’a’,1.2,(true,0));;

- : char * float * (bool * int) = (’a’,1.2,(true,0))

49/103 49

Page 74: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

n-uplets

Le produit cartesien (binaire) se generalise facilement afin deregrouper les valeurs en n-uplets

# (2+3,false||true,"bonjour");;

- : int * bool * string = (5,true,"bonjour")

Les n-uplets et les paires peuvent se melanger

# (’a’,1.2,(true,0));;

- : char * float * (bool * int) = (’a’,1.2,(true,0))

49/103 49

Page 75: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

n-uplets

Le produit cartesien (binaire) se generalise facilement afin deregrouper les valeurs en n-uplets

# (2+3,false||true,"bonjour");;

- : int * bool * string = (5,true,"bonjour")

Les n-uplets et les paires peuvent se melanger

# (’a’,1.2,(true,0));;

- : char * float * (bool * int) = (’a’,1.2,(true,0))

49/103 49

Page 76: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Ne pas confondre...

. . . les types suivants

int * int * int (int * int) * int int * (int * int)

I le premier designe un triplet d’entiersI le second est une paire dont la premiere composante est une

paire d’entiers et la deuxieme un entierI le troisieme est une paire dont la premiere composante est un

entier et la deuxieme composante est une paire d’entiers

50/103 50

Page 77: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Ne pas confondre...

. . . les types suivants

int * int * int (int * int) * int int * (int * int)

I le premier designe un triplet d’entiers

I le second est une paire dont la premiere composante est unepaire d’entiers et la deuxieme un entier

I le troisieme est une paire dont la premiere composante est unentier et la deuxieme composante est une paire d’entiers

50/103 50

Page 78: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Ne pas confondre...

. . . les types suivants

int * int * int (int * int) * int int * (int * int)

I le premier designe un triplet d’entiersI le second est une paire dont la premiere composante est une

paire d’entiers et la deuxieme un entier

I le troisieme est une paire dont la premiere composante est unentier et la deuxieme composante est une paire d’entiers

50/103 50

Page 79: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Ne pas confondre...

. . . les types suivants

int * int * int (int * int) * int int * (int * int)

I le premier designe un triplet d’entiersI le second est une paire dont la premiere composante est une

paire d’entiers et la deuxieme un entierI le troisieme est une paire dont la premiere composante est un

entier et la deuxieme composante est une paire d’entiers

50/103 50

Page 80: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un n-uplet (1/2)

On utilise une forme generalisee du let

let motif = e

ou une construction match-with

match e with

motif -> ...

ou le motif permet de filtrer le n-uplet represente par l’expression e

# let v = (’a’,1.2,"bonjour");;

val v : char * float * string = (’a’,1.2,"bonjour")

On recupere les elements de v avec (x,y,z) comme motif

# let (x,y,z) = v;;

val x : char = ’a’

val y : float = 1.2

val z : string = "bonjour"

51/103 51

Page 81: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un n-uplet (1/2)

On utilise une forme generalisee du let

let motif = e

ou une construction match-with

match e with

motif -> ...

ou le motif permet de filtrer le n-uplet represente par l’expression e

# let v = (’a’,1.2,"bonjour");;

val v : char * float * string = (’a’,1.2,"bonjour")

On recupere les elements de v avec (x,y,z) comme motif

# let (x,y,z) = v;;

val x : char = ’a’

val y : float = 1.2

val z : string = "bonjour"

51/103 51

Page 82: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un n-uplet (1/2)

On utilise une forme generalisee du let

let motif = e

ou une construction match-with

match e with

motif -> ...

ou le motif permet de filtrer le n-uplet represente par l’expression e

# let v = (’a’,1.2,"bonjour");;

val v : char * float * string = (’a’,1.2,"bonjour")

On recupere les elements de v avec (x,y,z) comme motif

# let (x,y,z) = v;;

val x : char = ’a’

val y : float = 1.2

val z : string = "bonjour"51/103 51

Page 83: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un n-uplet (2/2)

# let v = (1,(’a’,2.3));;

val v : int * (char * float) = (1,(’a’,2.3))

Acces aux composantes d’une paire

# let (x,c) = v;;

val x : int = 1

val c : char * float = (’a’,2.3)

Acces aux composantes d’une composante

# let (x,(y,z)) = v;;

val x : int = 1

val y : char = ’a’

val z : float = 2.3

52/103 52

Page 84: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un n-uplet (2/2)

# let v = (1,(’a’,2.3));;

val v : int * (char * float) = (1,(’a’,2.3))

Acces aux composantes d’une paire

# let (x,c) = v;;

val x : int = 1

val c : char * float = (’a’,2.3)

Acces aux composantes d’une composante

# let (x,(y,z)) = v;;

val x : int = 1

val y : char = ’a’

val z : float = 2.3

52/103 52

Page 85: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un n-uplet (2/2)

# let v = (1,(’a’,2.3));;

val v : int * (char * float) = (1,(’a’,2.3))

Acces aux composantes d’une paire

# let (x,c) = v;;

val x : int = 1

val c : char * float = (’a’,2.3)

Acces aux composantes d’une composante

# let (x,(y,z)) = v;;

val x : int = 1

val y : char = ’a’

val z : float = 2.3

52/103 52

Page 86: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un n-uplet (2/2)

# let v = (1,(’a’,2.3));;

val v : int * (char * float) = (1,(’a’,2.3))

Acces aux composantes d’une paire

# let (x,c) = v;;

val x : int = 1

val c : char * float = (’a’,2.3)

Acces aux composantes d’une composante

# let (x,(y,z)) = v;;

val x : int = 1

val y : char = ’a’

val z : float = 2.3

52/103 52

Page 87: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un n-uplet (2/2)

# let v = (1,(’a’,2.3));;

val v : int * (char * float) = (1,(’a’,2.3))

Acces aux composantes d’une paire

# let (x,c) = v;;

val x : int = 1

val c : char * float = (’a’,2.3)

Acces aux composantes d’une composante

# let (x,(y,z)) = v;;

val x : int = 1

val y : char = ’a’

val z : float = 2.3

52/103 52

Page 88: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

N-uplets : valeurs de premiere classe

Les n-uplets peuvent etre passes en arguments aux fonctions

# let f (x,y,z) = x + y * (int_of_float z);;

val f : int * int * float -> int = <fun>

# f (1,2,3.5);;

- : int = 7

ou retournes comme resultats

# let rec division n m =

if n<m then (0,n)

else

let (q,r) = division (n - m) m in (q + 1,r);;

val division : int -> int -> int * int = <fun>

53/103 53

Page 89: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

N-uplets : valeurs de premiere classe

Les n-uplets peuvent etre passes en arguments aux fonctions

# let f (x,y,z) = x + y * (int_of_float z);;

val f : int * int * float -> int = <fun>

# f (1,2,3.5);;

- : int = 7

ou retournes comme resultats

# let rec division n m =

if n<m then (0,n)

else

let (q,r) = division (n - m) m in (q + 1,r);;

val division : int -> int -> int * int = <fun>

53/103 53

Page 90: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

N-uplets : valeurs de premiere classe

Les n-uplets peuvent etre passes en arguments aux fonctions

# let f (x,y,z) = x + y * (int_of_float z);;

val f : int * int * float -> int = <fun>

# f (1,2,3.5);;

- : int = 7

ou retournes comme resultats

# let rec division n m =

if n<m then (0,n)

else

let (q,r) = division (n - m) m in (q + 1,r);;

val division : int -> int -> int * int = <fun>

53/103 53

Page 91: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

N-uplets : valeurs de premiere classe

Les n-uplets peuvent etre passes en arguments aux fonctions

# let f (x,y,z) = x + y * (int_of_float z);;

val f : int * int * float -> int = <fun>

# f (1,2,3.5);;

- : int = 7

ou retournes comme resultats

# let rec division n m =

if n<m then (0,n)

else

let (q,r) = division (n - m) m in (q + 1,r);;

val division : int -> int -> int * int = <fun>53/103 53

Page 92: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Exemple

Calcul efficace de la fonction de Fibonacci dans fibonacci.ml

let fibonacci n =

let rec fib_rapide n =

if n=0 then (0,1)

else let (x,y) = fib_rapide (n-1) in (y,x+y)

in

fst (fib_rapide n)

print_int (fibonacci 15);;

compilation

> ocamlc -o fibonacci fibonacci.ml

execution

> ./fibonacci

610

54/103 54

Page 93: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Exemple

Calcul efficace de la fonction de Fibonacci dans fibonacci.ml

let fibonacci n =

let rec fib_rapide n =

if n=0 then (0,1)

else let (x,y) = fib_rapide (n-1) in (y,x+y)

in

fst (fib_rapide n)

print_int (fibonacci 15);;

compilation

> ocamlc -o fibonacci fibonacci.ml

execution

> ./fibonacci

610

54/103 54

Page 94: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Exemple

Calcul efficace de la fonction de Fibonacci dans fibonacci.ml

let fibonacci n =

let rec fib_rapide n =

if n=0 then (0,1)

else let (x,y) = fib_rapide (n-1) in (y,x+y)

in

fst (fib_rapide n)

print_int (fibonacci 15);;

compilation

> ocamlc -o fibonacci fibonacci.ml

execution

> ./fibonacci

61054/103 54

Page 95: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Inconvenients des n-uplets (1/2)

I Les objets representes par des n-uplets ne sont pas identifiesde maniere unique

I Le systeme de types du langage ne peut donc pas etre utilisepour garantir de ”bonnes” proprietes

Exemple : on represente les nombres complexes par des paires(r,i) de type float*float ou r et i sont respectivement lapartie reelle et la partie imaginaire du complexe

I Malheureusement ce type peut tout aussi bien representerdes nombres complexes en notation polaire, ou desintervalles etc.

I Comment alors garantir que la fonction suivante est bienutilisee pour ajouter des complexes ?

# let add (r1,i1) (r2,i2) = (r1+.r2 , i1+.i2);;

val add: float*float -> float*float -> float*float = <fun>

55/103 55

Page 96: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Inconvenients des n-uplets (2/2)

Les n-uplets avec un grand nombre de composantes deviennenttres vite inutilisables en pratique

Exemple : une fiche d’un fichier de personnes (nom, prenom,adresse, date de naissance, telephone fixe, telephone portable,etc.)

# let v =

("Durand","Jacques",

("2 rue J.Monod", "Orsay Cedex", 91893),

(10,03,1967), "0130452637","0645362738" ...)

I La consultation des informations devient vite penibleI Plusieurs elements du n-uplet peuvent avoir le meme type

(ex. nom et prenom) et il est facile de les confondre (sans quele systeme de type puisse nous aider)

56/103 56

Page 97: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Produits Nommes

57/103 57

Page 98: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

les enregistrements

Le produit nomme permet de definir des enregistrements : desn-uplets dont les elements (champs) ont chacun un nom distinct

En OCAML, chaque produit nomme (ou type enregistrement)possede un nom donne par l’utilisateur

# type complexe = { re : float; im : float};;

type complexe = { re : float; im : float}

On cree des valeurs de type complexe de la maniere suivante

# { re = 1.4; im = 0.5};;

- : complexe = { re = 1.4; im = 0.5}

58/103 58

Page 99: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

les enregistrements

Le produit nomme permet de definir des enregistrements : desn-uplets dont les elements (champs) ont chacun un nom distinct

En OCAML, chaque produit nomme (ou type enregistrement)possede un nom donne par l’utilisateur

# type complexe = { re : float; im : float};;

type complexe = { re : float; im : float}

On cree des valeurs de type complexe de la maniere suivante

# { re = 1.4; im = 0.5};;

- : complexe = { re = 1.4; im = 0.5}

58/103 58

Page 100: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

les enregistrements

Le produit nomme permet de definir des enregistrements : desn-uplets dont les elements (champs) ont chacun un nom distinct

En OCAML, chaque produit nomme (ou type enregistrement)possede un nom donne par l’utilisateur

# type complexe = { re : float; im : float};;

type complexe = { re : float; im : float}

On cree des valeurs de type complexe de la maniere suivante

# { re = 1.4; im = 0.5};;

- : complexe = { re = 1.4; im = 0.5}

58/103 58

Page 101: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

les enregistrements

Le produit nomme permet de definir des enregistrements : desn-uplets dont les elements (champs) ont chacun un nom distinct

En OCAML, chaque produit nomme (ou type enregistrement)possede un nom donne par l’utilisateur

# type complexe = { re : float; im : float};;

type complexe = { re : float; im : float}

On cree des valeurs de type complexe de la maniere suivante

# { re = 1.4; im = 0.5};;

- : complexe = { re = 1.4; im = 0.5}

58/103 58

Page 102: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un enregistrement (1/2)

L’acces le plus simple aux champs d’un enregistrement se fait al’aide de la notation

objet.nom du champ

# let v = { re = 1.3; im = 0.9};;

val v : complexe = { re = 1.3; im = 0.9}

# v.re;;

- : float = 1.3

59/103 59

Page 103: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un enregistrement (1/2)

L’acces le plus simple aux champs d’un enregistrement se fait al’aide de la notation

objet.nom du champ

# let v = { re = 1.3; im = 0.9};;

val v : complexe = { re = 1.3; im = 0.9}

# v.re;;

- : float = 1.3

59/103 59

Page 104: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un enregistrement (1/2)

L’acces le plus simple aux champs d’un enregistrement se fait al’aide de la notation

objet.nom du champ

# let v = { re = 1.3; im = 0.9};;

val v : complexe = { re = 1.3; im = 0.9}

# v.re;;

- : float = 1.3

59/103 59

Page 105: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un enregistrement (2/2)

Le filtrage permet un acces partiel et en profondeur aux champsd’un enregistrement

# type t = { a : int; b : float * char; c : string };;

type t = { a : int; b : float * char; c : string }

# let v = { a = 1; b = (3.4,’a’); c = "bonjour" };;

val v : t = { a = 1; b = (3.4,’a’); c = "bonjour" }

# let { b = (_,x); c = y} = v;;

val x : char = ’a’

val y : string = "bonjour"

60/103 60

Page 106: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un enregistrement (2/2)

Le filtrage permet un acces partiel et en profondeur aux champsd’un enregistrement

# type t = { a : int; b : float * char; c : string };;

type t = { a : int; b : float * char; c : string }

# let v = { a = 1; b = (3.4,’a’); c = "bonjour" };;

val v : t = { a = 1; b = (3.4,’a’); c = "bonjour" }

# let { b = (_,x); c = y} = v;;

val x : char = ’a’

val y : string = "bonjour"

60/103 60

Page 107: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’un enregistrement (2/2)

Le filtrage permet un acces partiel et en profondeur aux champsd’un enregistrement

# type t = { a : int; b : float * char; c : string };;

type t = { a : int; b : float * char; c : string }

# let v = { a = 1; b = (3.4,’a’); c = "bonjour" };;

val v : t = { a = 1; b = (3.4,’a’); c = "bonjour" }

# let { b = (_,x); c = y} = v;;

val x : char = ’a’

val y : string = "bonjour"

60/103 60

Page 108: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

L’ordre des champs n’a pas d’importance

Les definitions de types suivantes sont equivalentes

type t = { a : int; b : char; c : bool }

type t = { b : char; c : bool; a : int }

De meme ces valeurs sont egales :

# { a = 1; b = ’t’; c = true} = { b = ’t’; c = true; a = 1} ;;

- : bool = true

Le filtrage est egalement insensible a l’ordre des champs :

# let { c = x; b = y} = { b = ’t’; c = true; a = 1} ;;

val x : bool = true

val y : char = ’t’

61/103 61

Page 109: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

L’ordre des champs n’a pas d’importance

Les definitions de types suivantes sont equivalentes

type t = { a : int; b : char; c : bool }

type t = { b : char; c : bool; a : int }

De meme ces valeurs sont egales :

# { a = 1; b = ’t’; c = true} = { b = ’t’; c = true; a = 1} ;;

- : bool = true

Le filtrage est egalement insensible a l’ordre des champs :

# let { c = x; b = y} = { b = ’t’; c = true; a = 1} ;;

val x : bool = true

val y : char = ’t’

61/103 61

Page 110: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

L’ordre des champs n’a pas d’importance

Les definitions de types suivantes sont equivalentes

type t = { a : int; b : char; c : bool }

type t = { b : char; c : bool; a : int }

De meme ces valeurs sont egales :

# { a = 1; b = ’t’; c = true} = { b = ’t’; c = true; a = 1} ;;

- : bool = true

Le filtrage est egalement insensible a l’ordre des champs :

# let { c = x; b = y} = { b = ’t’; c = true; a = 1} ;;

val x : bool = true

val y : char = ’t’

61/103 61

Page 111: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

structurer l’information

Le melange des n-uplets et des enregistrements permet de definirdes objets complexes

# type adresse = { rue : string; ville : string; cp : int};;

# type fiche = {

nom : string;

prenom : string ;

adresse : adresse;

date_naissance : int * int * int;

tel_fixe : string;

portable : string

};;

62/103 62

Page 112: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Creation de nouvelles valeurs

# let v1 = { a = 1; b = false; c = ’r’};;

val v1 : t = { a = 1; b = false; c = ’r’}

On peut creer un nouvel enregistrement v2 en utilisant le contenudes champs de v1

# let v2 = { a = v1.a; b = true; c = v1.c};;

val v2 : t = { a = 1; b = true; c = ’r’}

Le raccourci syntaxique suivant permet d’arriver au meme resultat

{v with c1 = e1; ... cn=en}

# let v3 = { v1 with b = true };;

val v3 : t = { a = 1; b = true; c = ’r’}

63/103 63

Page 113: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Creation de nouvelles valeurs

# let v1 = { a = 1; b = false; c = ’r’};;

val v1 : t = { a = 1; b = false; c = ’r’}

On peut creer un nouvel enregistrement v2 en utilisant le contenudes champs de v1

# let v2 = { a = v1.a; b = true; c = v1.c};;

val v2 : t = { a = 1; b = true; c = ’r’}

Le raccourci syntaxique suivant permet d’arriver au meme resultat

{v with c1 = e1; ... cn=en}

# let v3 = { v1 with b = true };;

val v3 : t = { a = 1; b = true; c = ’r’}

63/103 63

Page 114: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Creation de nouvelles valeurs

# let v1 = { a = 1; b = false; c = ’r’};;

val v1 : t = { a = 1; b = false; c = ’r’}

On peut creer un nouvel enregistrement v2 en utilisant le contenudes champs de v1

# let v2 = { a = v1.a; b = true; c = v1.c};;

val v2 : t = { a = 1; b = true; c = ’r’}

Le raccourci syntaxique suivant permet d’arriver au meme resultat

{v with c1 = e1; ... cn=en}

# let v3 = { v1 with b = true };;

val v3 : t = { a = 1; b = true; c = ’r’}

63/103 63

Page 115: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Creation de nouvelles valeurs

# let v1 = { a = 1; b = false; c = ’r’};;

val v1 : t = { a = 1; b = false; c = ’r’}

On peut creer un nouvel enregistrement v2 en utilisant le contenudes champs de v1

# let v2 = { a = v1.a; b = true; c = v1.c};;

val v2 : t = { a = 1; b = true; c = ’r’}

Le raccourci syntaxique suivant permet d’arriver au meme resultat

{v with c1 = e1; ... cn=en}

# let v3 = { v1 with b = true };;

val v3 : t = { a = 1; b = true; c = ’r’}

63/103 63

Page 116: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Creation de nouvelles valeurs

# let v1 = { a = 1; b = false; c = ’r’};;

val v1 : t = { a = 1; b = false; c = ’r’}

On peut creer un nouvel enregistrement v2 en utilisant le contenudes champs de v1

# let v2 = { a = v1.a; b = true; c = v1.c};;

val v2 : t = { a = 1; b = true; c = ’r’}

Le raccourci syntaxique suivant permet d’arriver au meme resultat

{v with c1 = e1; ... cn=en}

# let v3 = { v1 with b = true };;

val v3 : t = { a = 1; b = true; c = ’r’}

63/103 63

Page 117: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Enregistrements : valeurs de premiere classe

Une fonction prenant un enregistrement en argument :

# let f v = v.a;;

val f : t -> int

# f {a = 1; b = false; c = ’e’};;

- : int = 1

Les enregistrements peuvent aussi etre retournes en resultat

# let f {a=x} v = { v with a = x+v.a } ;;

val f : t -> t -> t

# let v = {a=1;b=true;c=’r’} in f v v;;

- : t = {a=2;b=true;c=’r’}

64/103 64

Page 118: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Enregistrements : valeurs de premiere classe

Une fonction prenant un enregistrement en argument :

# let f v = v.a;;

val f : t -> int

# f {a = 1; b = false; c = ’e’};;

- : int = 1

Les enregistrements peuvent aussi etre retournes en resultat

# let f {a=x} v = { v with a = x+v.a } ;;

val f : t -> t -> t

# let v = {a=1;b=true;c=’r’} in f v v;;

- : t = {a=2;b=true;c=’r’}

64/103 64

Page 119: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Enregistrements : valeurs de premiere classe

Une fonction prenant un enregistrement en argument :

# let f v = v.a;;

val f : t -> int

# f {a = 1; b = false; c = ’e’};;

- : int = 1

Les enregistrements peuvent aussi etre retournes en resultat

# let f {a=x} v = { v with a = x+v.a } ;;

val f : t -> t -> t

# let v = {a=1;b=true;c=’r’} in f v v;;

- : t = {a=2;b=true;c=’r’}

64/103 64

Page 120: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Enregistrements : valeurs de premiere classe

Une fonction prenant un enregistrement en argument :

# let f v = v.a;;

val f : t -> int

# f {a = 1; b = false; c = ’e’};;

- : int = 1

Les enregistrements peuvent aussi etre retournes en resultat

# let f {a=x} v = { v with a = x+v.a } ;;

val f : t -> t -> t

# let v = {a=1;b=true;c=’r’} in f v v;;

- : t = {a=2;b=true;c=’r’}

64/103 64

Page 121: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Sommes

65/103 65

Page 122: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Les types sommes

I Modelisation de domaines finisI Realisation de sommes disjointes permettant de reunir dans

un meme type des valeurs pouvant appartenir a des typesdifferents

66/103 66

Page 123: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Constructeurs constants

On peut modeliser un domaine fini comportant exactement nvaleurs avec un type somme

Exemple, les couleurs d’un jeu de carte :

# type couleur = Pique | Coeur | Carreau | Trefle;;

type couleur = Pique | Coeur | Carreau | Trefle

I les identificateurs Pique, Coeur, Carreau et Trefle sont desconstructeurs (les majuscules sont obligatoires pour definirdes constructeurs)

I le nom du domaine fini est couleur

67/103 67

Page 124: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Utilisation des constructeurs

L’unique maniere de creer des valeurs d’un type somme estd’utiliser un constructeur :

# Trefle;;

- : couleur = Trefle

# let v = (Pique , Coeur);;

val v : couleur * couleur = (Pique , Coeur)

# Pique = Coeur;;

- : bool = false

68/103 68

Page 125: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Utilisation des constructeurs

L’unique maniere de creer des valeurs d’un type somme estd’utiliser un constructeur :

# Trefle;;

- : couleur = Trefle

# let v = (Pique , Coeur);;

val v : couleur * couleur = (Pique , Coeur)

# Pique = Coeur;;

- : bool = false

68/103 68

Page 126: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Utilisation des constructeurs

L’unique maniere de creer des valeurs d’un type somme estd’utiliser un constructeur :

# Trefle;;

- : couleur = Trefle

# let v = (Pique , Coeur);;

val v : couleur * couleur = (Pique , Coeur)

# Pique = Coeur;;

- : bool = false

68/103 68

Page 127: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Utilisation des constructeurs

L’unique maniere de creer des valeurs d’un type somme estd’utiliser un constructeur :

# Trefle;;

- : couleur = Trefle

# let v = (Pique , Coeur);;

val v : couleur * couleur = (Pique , Coeur)

# Pique = Coeur;;

- : bool = false

68/103 68

Page 128: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Filtrage des constructeurs constants

La construction match-with permet de definir de maniere compacteune analyse par cas d’un type somme

# let points v =

match v with

Pique -> 1

| Trefle -> 2

| Coeur -> 3

| Carreau -> 4;;

val points : couleur -> int = <fun>

# points Coeur;;

- : int = 3

69/103 69

Page 129: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Filtrage des constructeurs constants

La construction match-with permet de definir de maniere compacteune analyse par cas d’un type somme

# let points v =

match v with

Pique -> 1

| Trefle -> 2

| Coeur -> 3

| Carreau -> 4;;

val points : couleur -> int = <fun>

# points Coeur;;

- : int = 3

69/103 69

Page 130: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Filtrage des constructeurs constants

La construction match-with permet de definir de maniere compacteune analyse par cas d’un type somme

# let points v =

match v with

Pique -> 1

| Trefle -> 2

| Coeur -> 3

| Carreau -> 4;;

val points : couleur -> int = <fun>

# points Coeur;;

- : int = 3

69/103 69

Page 131: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Filtrage des constructeurs constants

La construction match-with permet de definir de maniere compacteune analyse par cas d’un type somme

# let points v =

match v with

Pique -> 1

| Trefle -> 2

| Coeur -> 3

| Carreau -> 4;;

val points : couleur -> int = <fun>

# points Coeur;;

- : int = 3

69/103 69

Page 132: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Constructeurs avec arguments

Les constructeurs peuvent egalement avoir des arguments, parexemple :

# type num = Int of int | Float of float

type num = Int of int | Float of float

Le mot-cle of indique que le constructeur attend un argument

On cree des valeurs en appliquant les constructeurs a desarguments du bon type :

# Int(5);;

- : num = Int(5)

70/103 70

Page 133: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Constructeurs avec arguments

Les constructeurs peuvent egalement avoir des arguments, parexemple :

# type num = Int of int | Float of float

type num = Int of int | Float of float

Le mot-cle of indique que le constructeur attend un argument

On cree des valeurs en appliquant les constructeurs a desarguments du bon type :

# Int(5);;

- : num = Int(5)

70/103 70

Page 134: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Filtrage des constructeurs avec arguments (1/2)

On utilise la construction match-with pour recuperer les argumentsassocies a un constructeur

# match Int(5) with Int(x) -> x+2;;

- : int = 7

En realite, la reponse que l’on obtient est celle-la :

Warning P: this pattern-matching is not exhaustive.

Here is an example of a value that is not matched:

Float _

- : int = 7

Le filtrage exige de faire une analyse par cas complete en fonctiondu type de l’objet filtre et non de sa valeur.

71/103 71

Page 135: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Filtrage des constructeurs avec arguments (1/2)

On utilise la construction match-with pour recuperer les argumentsassocies a un constructeur

# match Int(5) with Int(x) -> x+2;;

- : int = 7

En realite, la reponse que l’on obtient est celle-la :

Warning P: this pattern-matching is not exhaustive.

Here is an example of a value that is not matched:

Float _

- : int = 7

Le filtrage exige de faire une analyse par cas complete en fonctiondu type de l’objet filtre et non de sa valeur.

71/103 71

Page 136: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Filtrage des constructeurs avec arguments (1/2)

On utilise la construction match-with pour recuperer les argumentsassocies a un constructeur

# match Int(5) with Int(x) -> x+2;;

- : int = 7

En realite, la reponse que l’on obtient est celle-la :

Warning P: this pattern-matching is not exhaustive.

Here is an example of a value that is not matched:

Float _

- : int = 7

Le filtrage exige de faire une analyse par cas complete en fonctiondu type de l’objet filtre et non de sa valeur.

71/103 71

Page 137: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Filtrage des constructeurs avec arguments (2/2)

La completude de l’analyse peut etre obtenue en executantfailwith "explication" pour les cas impossibles

# match Int(5) with

Int(x) -> x+2

| Float(x) -> failwith "cas impossible";;

- : int = 7

72/103 72

Page 138: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Filtrage des constructeurs avec arguments (2/2)

La completude de l’analyse peut etre obtenue en executantfailwith "explication" pour les cas impossibles

# match Int(5) with

Int(x) -> x+2

| Float(x) -> failwith "cas impossible";;

- : int = 7

72/103 72

Page 139: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Exemple

L’addition de valeurs de type num peut s’ecrire ainsi

# let ajoute x y =

match (x,y) with

(Int(m) , Int(n)) -> Int(m + n)

| (Int(m) , Float(n)) -> Float((float_of_int m) +. n)

| (Float(m) , Int(n)) -> Float(m +. (float_of_int n))

| (Float(m) , Float(n)) -> Float(m +. n);;

val ajoute : num -> num -> num = <fun>

On utilise simplement cette fonction de la maniere suivante

# ajoute (Float(3.5)) (Int(5));;

- : num = Float(8.5)

73/103 73

Page 140: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Exemple

L’addition de valeurs de type num peut s’ecrire ainsi

# let ajoute x y =

match (x,y) with

(Int(m) , Int(n)) -> Int(m + n)

| (Int(m) , Float(n)) -> Float((float_of_int m) +. n)

| (Float(m) , Int(n)) -> Float(m +. (float_of_int n))

| (Float(m) , Float(n)) -> Float(m +. n);;

val ajoute : num -> num -> num = <fun>

On utilise simplement cette fonction de la maniere suivante

# ajoute (Float(3.5)) (Int(5));;

- : num = Float(8.5)

73/103 73

Page 141: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Exemple

L’addition de valeurs de type num peut s’ecrire ainsi

# let ajoute x y =

match (x,y) with

(Int(m) , Int(n)) -> Int(m + n)

| (Int(m) , Float(n)) -> Float((float_of_int m) +. n)

| (Float(m) , Int(n)) -> Float(m +. (float_of_int n))

| (Float(m) , Float(n)) -> Float(m +. n);;

val ajoute : num -> num -> num = <fun>

On utilise simplement cette fonction de la maniere suivante

# ajoute (Float(3.5)) (Int(5));;

- : num = Float(8.5)

73/103 73

Page 142: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Exemple

L’addition de valeurs de type num peut s’ecrire ainsi

# let ajoute x y =

match (x,y) with

(Int(m) , Int(n)) -> Int(m + n)

| (Int(m) , Float(n)) -> Float((float_of_int m) +. n)

| (Float(m) , Int(n)) -> Float(m +. (float_of_int n))

| (Float(m) , Float(n)) -> Float(m +. n);;

val ajoute : num -> num -> num = <fun>

On utilise simplement cette fonction de la maniere suivante

# ajoute (Float(3.5)) (Int(5));;

- : num = Float(8.5)

73/103 73

Page 143: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Autre exemple

Le type des cartes d’un jeu de cartes :

type valeur = Roi | Reine | Valet | Num of int

type couleur = Coeur | Pique | Trefle | Carreau

type carte = valeur * couleur

# let compare (c1,_) (c2,_) =

if c1 = c2 then 0

else match c1,c2 with

| Roi, _ -> 1

| Reine, Roi -> -1

| Reine, _ -> 1

| Valet, Roi -> -1

| Valet, Reine -> -1

| Valet, _ -> 1

| Num(x), Num(y) -> (x - y) / (abs (x - y))

| _ -> -1

74/103 74

Page 144: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le type des sequences (listes)

75/103 75

Page 145: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Sequences d’entiers

On peut utiliser un type somme pour representer des sequences(non bornees) d’entiers :

# type int_list = Nil | Cons of int * int_list;;

I Nil represente la sequence videI Cons(x,l) est la sequence dont le premier element (on dit

aussi la tete) est x et la suite est la sequence l

Par exemple, la sequence 4;1;5;8;1 est representee par lavaleur :

# Cons(4,Cons(1,Cons(5,Cons(8,Cons(1,Nil)))));;

- : int_list = Cons(4,Cons(1,Cons(5,Cons(8,Cons(1,Nil)))))

76/103 76

Page 146: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Le type int list

Le type des sequences est predefini en OCAML et ses elementsse notent avec une syntaxe speciale

I Cons se note :: et est infixeI Nil se note []

Par exemple, la sequence 4;1;5;8;1 est representee par :

# 4::1::5::8::1::[];;

- : int list = [4;1;5;8;1]

On peut aussi directement utiliser la notation [e1;e2;...;en]

# [4;1;5;8;1];;

- : int list = [4;1;5;8;1]

ou faire un melange des deux notations :

# 4::1::[5;8;1];;

- : int list = [4;1;5;8;1]77/103 77

Page 147: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Des listes de types quelconques

OCAML permet de definir des listes dont les elements peuvent etreautre chose que des entiers :

# [’c’;’a’;’m’;’l’];;

- : char list = [’c’;’a’;’m’;’l’]

# [["des";"listes"];["de";"listes"]];;

- : string list list = [["des";"listes"];["de";"listes"]]

Mais il n’est pas possible de construire une liste d’elements detypes differents :

# [10;’a’;4];;

---

This expression has type char but is here used

with type int

78/103 78

Page 148: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Listes chaınees

Les listes predefinies en OCAML correspondent exactement auxlistes chaınees definies habituellement en C par le type suivant

typedef struct list{

int elt;

struct list* suivant;

};

La representation memoire de ces listes correspond a un chaınagede blocs memoire, par exemple, la liste [1; 2; 3] correspond a :

1 2

30 ([])

79/103 79

Page 149: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Acces aux elements d’une liste

On accede aux elements d’une liste a l’aide des fonctionspredefinies List.hd et List.tl

# List.hd [3;6;1;2];;

- : int = 3

# List.tl [3;6;1;2];;

- : int list = [6;1;2];;

List.hd et List.tl echouent sur une liste vide

# List.hd [];;

Exception: Failure "hd".

# List.tail [];;

Exception: Failure "tl".

80/103 80

Page 150: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions sur les listes

81/103 81

Page 151: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Definitions de fonctions sur les listes

La definition des fonctions sur les listes prennent generalement laforme d’une definition a deux cas :

I le cas ou liste est videI le cas ou elle ne l’est pas

Pour cette raison, il est plus agreable de realiser cette analyse parcas avec du filtrage :

# let f l =

match l with

[] -> ...

| x::s -> ...

82/103 82

Page 152: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

la fonction zeros

La fonction zeros verifie que tous les elements d’une listed’entiers sont des 0 (renvoie true si la liste est vide)

# let rec zeros l =

match l with

[] -> true

| x::s -> x=0 && zeros s ;;

val zeros : int list -> bool = <fun>

# zeros [];;

- : bool = true

# zeros [0;0;0];;

- : bool = true

# zeros [0;1;0];;

- : bool = false

83/103 83

Page 153: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

la fonction zeros

La fonction zeros verifie que tous les elements d’une listed’entiers sont des 0 (renvoie true si la liste est vide)

# let rec zeros l =

match l with

[] -> true

| x::s -> x=0 && zeros s ;;

val zeros : int list -> bool = <fun>

# zeros [];;

- : bool = true

# zeros [0;0;0];;

- : bool = true

# zeros [0;1;0];;

- : bool = false

83/103 83

Page 154: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

la fonction zeros

La fonction zeros verifie que tous les elements d’une listed’entiers sont des 0 (renvoie true si la liste est vide)

# let rec zeros l =

match l with

[] -> true

| x::s -> x=0 && zeros s ;;

val zeros : int list -> bool = <fun>

# zeros [];;

- : bool = true

# zeros [0;0;0];;

- : bool = true

# zeros [0;1;0];;

- : bool = false

83/103 83

Page 155: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

la fonction zeros

La fonction zeros verifie que tous les elements d’une listed’entiers sont des 0 (renvoie true si la liste est vide)

# let rec zeros l =

match l with

[] -> true

| x::s -> x=0 && zeros s ;;

val zeros : int list -> bool = <fun>

# zeros [];;

- : bool = true

# zeros [0;0;0];;

- : bool = true

# zeros [0;1;0];;

- : bool = false

83/103 83

Page 156: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction zeros

Evaluation de zeros [0;0;0]

zeros [0;0;0]

[0; 0; 0] 6= [], x = 0, s = [0; 0] ⇒ 0=0 && zeros [0;0]

= zeros [0;0]

[0; 0] 6= [], x = 0, s = [0] ⇒ 0=0 && zeros [0]

= zeros [0]

[0] 6= [], x = 0, s = [] ⇒ 0=0 && zeros []

= zeros []

[] = [] ⇒ true

Evaluation de zeros [0;1;0]

zeros [0;1;0]

[0; 1; 0] 6= [], x = 0, s = [1; 0] ⇒ 0=0 && zeros [1;0]

= zeros [1;0]

[1; 0] 6= [], x = 1, s = [0] ⇒ 1=0 && zeros [0]

= false

84/103 84

Page 157: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction zeros

Evaluation de zeros [0;0;0]

zeros [0;0;0]

[0; 0; 0] 6= [], x = 0, s = [0; 0] ⇒ 0=0 && zeros [0;0]

= zeros [0;0]

[0; 0] 6= [], x = 0, s = [0] ⇒ 0=0 && zeros [0]

= zeros [0]

[0] 6= [], x = 0, s = [] ⇒ 0=0 && zeros []

= zeros []

[] = [] ⇒ true

Evaluation de zeros [0;1;0]

zeros [0;1;0]

[0; 1; 0] 6= [], x = 0, s = [1; 0] ⇒ 0=0 && zeros [1;0]

= zeros [1;0]

[1; 0] 6= [], x = 1, s = [0] ⇒ 1=0 && zeros [0]

= false

84/103 84

Page 158: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction zeros

Evaluation de zeros [0;0;0]

zeros [0;0;0]

[0; 0; 0] 6= [], x = 0, s = [0; 0] ⇒ 0=0 && zeros [0;0]

= zeros [0;0]

[0; 0] 6= [], x = 0, s = [0] ⇒ 0=0 && zeros [0]

= zeros [0]

[0] 6= [], x = 0, s = [] ⇒ 0=0 && zeros []

= zeros []

[] = [] ⇒ true

Evaluation de zeros [0;1;0]

zeros [0;1;0]

[0; 1; 0] 6= [], x = 0, s = [1; 0] ⇒ 0=0 && zeros [1;0]

= zeros [1;0]

[1; 0] 6= [], x = 1, s = [0] ⇒ 1=0 && zeros [0]

= false

84/103 84

Page 159: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction zeros

Evaluation de zeros [0;0;0]

zeros [0;0;0]

[0; 0; 0] 6= [], x = 0, s = [0; 0] ⇒ 0=0 && zeros [0;0]

= zeros [0;0]

[0; 0] 6= [], x = 0, s = [0] ⇒ 0=0 && zeros [0]

= zeros [0]

[0] 6= [], x = 0, s = [] ⇒ 0=0 && zeros []

= zeros []

[] = [] ⇒ true

Evaluation de zeros [0;1;0]

zeros [0;1;0]

[0; 1; 0] 6= [], x = 0, s = [1; 0] ⇒ 0=0 && zeros [1;0]

= zeros [1;0]

[1; 0] 6= [], x = 1, s = [0] ⇒ 1=0 && zeros [0]

= false

84/103 84

Page 160: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction zeros

Evaluation de zeros [0;0;0]

zeros [0;0;0]

[0; 0; 0] 6= [], x = 0, s = [0; 0] ⇒ 0=0 && zeros [0;0]

= zeros [0;0]

[0; 0] 6= [], x = 0, s = [0] ⇒ 0=0 && zeros [0]

= zeros [0]

[0] 6= [], x = 0, s = [] ⇒ 0=0 && zeros []

= zeros []

[] = [] ⇒ true

Evaluation de zeros [0;1;0]

zeros [0;1;0]

[0; 1; 0] 6= [], x = 0, s = [1; 0] ⇒ 0=0 && zeros [1;0]

= zeros [1;0]

[1; 0] 6= [], x = 1, s = [0] ⇒ 1=0 && zeros [0]

= false

84/103 84

Page 161: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction zeros

Evaluation de zeros [0;0;0]

zeros [0;0;0]

[0; 0; 0] 6= [], x = 0, s = [0; 0] ⇒ 0=0 && zeros [0;0]

= zeros [0;0]

[0; 0] 6= [], x = 0, s = [0] ⇒ 0=0 && zeros [0]

= zeros [0]

[0] 6= [], x = 0, s = [] ⇒ 0=0 && zeros []

= zeros []

[] = [] ⇒ true

Evaluation de zeros [0;1;0]

zeros [0;1;0]

[0; 1; 0] 6= [], x = 0, s = [1; 0] ⇒ 0=0 && zeros [1;0]

= zeros [1;0]

[1; 0] 6= [], x = 1, s = [0] ⇒ 1=0 && zeros [0]

= false

84/103 84

Page 162: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction zeros

Evaluation de zeros [0;0;0]

zeros [0;0;0]

[0; 0; 0] 6= [], x = 0, s = [0; 0] ⇒ 0=0 && zeros [0;0]

= zeros [0;0]

[0; 0] 6= [], x = 0, s = [0] ⇒ 0=0 && zeros [0]

= zeros [0]

[0] 6= [], x = 0, s = [] ⇒ 0=0 && zeros []

= zeros []

[] = [] ⇒ true

Evaluation de zeros [0;1;0]

zeros [0;1;0]

[0; 1; 0] 6= [], x = 0, s = [1; 0] ⇒ 0=0 && zeros [1;0]

= zeros [1;0]

[1; 0] 6= [], x = 1, s = [0] ⇒ 1=0 && zeros [0]

= false

84/103 84

Page 163: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction zeros

Evaluation de zeros [0;0;0]

zeros [0;0;0]

[0; 0; 0] 6= [], x = 0, s = [0; 0] ⇒ 0=0 && zeros [0;0]

= zeros [0;0]

[0; 0] 6= [], x = 0, s = [0] ⇒ 0=0 && zeros [0]

= zeros [0]

[0] 6= [], x = 0, s = [] ⇒ 0=0 && zeros []

= zeros []

[] = [] ⇒ true

Evaluation de zeros [0;1;0]

zeros [0;1;0]

[0; 1; 0] 6= [], x = 0, s = [1; 0] ⇒ 0=0 && zeros [1;0]

= zeros [1;0]

[1; 0] 6= [], x = 1, s = [0] ⇒ 1=0 && zeros [0]

= false

84/103 84

Page 164: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recherche d’un entier dans une liste

La fonction recherche determine si un entier n figure bien dansune liste l

# let rec recherche n l =

match l with

[] -> false

| x::s -> x=n || recherche n s

val recherche : int list -> bool = <fun>

# recherche 4 [3;2;4;1];;

- : bool = true

# recherche 4 [1;2];;

- : bool = false

85/103 85

Page 165: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recherche d’un entier dans une liste

La fonction recherche determine si un entier n figure bien dansune liste l

# let rec recherche n l =

match l with

[] -> false

| x::s -> x=n || recherche n s

val recherche : int list -> bool = <fun>

# recherche 4 [3;2;4;1];;

- : bool = true

# recherche 4 [1;2];;

- : bool = false

85/103 85

Page 166: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recherche d’un entier dans une liste

La fonction recherche determine si un entier n figure bien dansune liste l

# let rec recherche n l =

match l with

[] -> false

| x::s -> x=n || recherche n s

val recherche : int list -> bool = <fun>

# recherche 4 [3;2;4;1];;

- : bool = true

# recherche 4 [1;2];;

- : bool = false

85/103 85

Page 167: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction recherche

Evaluation de recherche 4 [3;2;4;1]

recherche 4 [3;2;4;1]

[3; 2; 4; 1] 6= [], x = 3, s = [2; 4; 1] ⇒ 3=4 || recherche 4 [2;4;1]

= recherche 4 [2;4;1]

[2; 4; 1] 6= [], x = 2, s = [4; 1] ⇒ 2=4 || recherche [4;1]

= recherche 4 [4;1]

[4; 1] 6= [], x = 4, s = [1] ⇒ 4=4 || recherche 4 [1]

= true

Evaluation de recherche 4 [1;2]

recherche 4 [1;2]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1=4 || recherche 4 [2]

= recherche 4 [2]

[2] 6= [], x = 2, s = [] ⇒ 2=4 || recherche 4 []

= recherche 4 []

[] = [] ⇒ false

86/103 86

Page 168: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction recherche

Evaluation de recherche 4 [3;2;4;1]

recherche 4 [3;2;4;1]

[3; 2; 4; 1] 6= [], x = 3, s = [2; 4; 1] ⇒ 3=4 || recherche 4 [2;4;1]

= recherche 4 [2;4;1]

[2; 4; 1] 6= [], x = 2, s = [4; 1] ⇒ 2=4 || recherche [4;1]

= recherche 4 [4;1]

[4; 1] 6= [], x = 4, s = [1] ⇒ 4=4 || recherche 4 [1]

= true

Evaluation de recherche 4 [1;2]

recherche 4 [1;2]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1=4 || recherche 4 [2]

= recherche 4 [2]

[2] 6= [], x = 2, s = [] ⇒ 2=4 || recherche 4 []

= recherche 4 []

[] = [] ⇒ false

86/103 86

Page 169: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction recherche

Evaluation de recherche 4 [3;2;4;1]

recherche 4 [3;2;4;1]

[3; 2; 4; 1] 6= [], x = 3, s = [2; 4; 1] ⇒ 3=4 || recherche 4 [2;4;1]

= recherche 4 [2;4;1]

[2; 4; 1] 6= [], x = 2, s = [4; 1] ⇒ 2=4 || recherche [4;1]

= recherche 4 [4;1]

[4; 1] 6= [], x = 4, s = [1] ⇒ 4=4 || recherche 4 [1]

= true

Evaluation de recherche 4 [1;2]

recherche 4 [1;2]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1=4 || recherche 4 [2]

= recherche 4 [2]

[2] 6= [], x = 2, s = [] ⇒ 2=4 || recherche 4 []

= recherche 4 []

[] = [] ⇒ false

86/103 86

Page 170: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction recherche

Evaluation de recherche 4 [3;2;4;1]

recherche 4 [3;2;4;1]

[3; 2; 4; 1] 6= [], x = 3, s = [2; 4; 1] ⇒ 3=4 || recherche 4 [2;4;1]

= recherche 4 [2;4;1]

[2; 4; 1] 6= [], x = 2, s = [4; 1] ⇒ 2=4 || recherche [4;1]

= recherche 4 [4;1]

[4; 1] 6= [], x = 4, s = [1] ⇒ 4=4 || recherche 4 [1]

= true

Evaluation de recherche 4 [1;2]

recherche 4 [1;2]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1=4 || recherche 4 [2]

= recherche 4 [2]

[2] 6= [], x = 2, s = [] ⇒ 2=4 || recherche 4 []

= recherche 4 []

[] = [] ⇒ false

86/103 86

Page 171: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction recherche

Evaluation de recherche 4 [3;2;4;1]

recherche 4 [3;2;4;1]

[3; 2; 4; 1] 6= [], x = 3, s = [2; 4; 1] ⇒ 3=4 || recherche 4 [2;4;1]

= recherche 4 [2;4;1]

[2; 4; 1] 6= [], x = 2, s = [4; 1] ⇒ 2=4 || recherche [4;1]

= recherche 4 [4;1]

[4; 1] 6= [], x = 4, s = [1] ⇒ 4=4 || recherche 4 [1]

= true

Evaluation de recherche 4 [1;2]

recherche 4 [1;2]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1=4 || recherche 4 [2]

= recherche 4 [2]

[2] 6= [], x = 2, s = [] ⇒ 2=4 || recherche 4 []

= recherche 4 []

[] = [] ⇒ false

86/103 86

Page 172: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction recherche

Evaluation de recherche 4 [3;2;4;1]

recherche 4 [3;2;4;1]

[3; 2; 4; 1] 6= [], x = 3, s = [2; 4; 1] ⇒ 3=4 || recherche 4 [2;4;1]

= recherche 4 [2;4;1]

[2; 4; 1] 6= [], x = 2, s = [4; 1] ⇒ 2=4 || recherche [4;1]

= recherche 4 [4;1]

[4; 1] 6= [], x = 4, s = [1] ⇒ 4=4 || recherche 4 [1]

= true

Evaluation de recherche 4 [1;2]

recherche 4 [1;2]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1=4 || recherche 4 [2]

= recherche 4 [2]

[2] 6= [], x = 2, s = [] ⇒ 2=4 || recherche 4 []

= recherche 4 []

[] = [] ⇒ false

86/103 86

Page 173: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction recherche

Evaluation de recherche 4 [3;2;4;1]

recherche 4 [3;2;4;1]

[3; 2; 4; 1] 6= [], x = 3, s = [2; 4; 1] ⇒ 3=4 || recherche 4 [2;4;1]

= recherche 4 [2;4;1]

[2; 4; 1] 6= [], x = 2, s = [4; 1] ⇒ 2=4 || recherche [4;1]

= recherche 4 [4;1]

[4; 1] 6= [], x = 4, s = [1] ⇒ 4=4 || recherche 4 [1]

= true

Evaluation de recherche 4 [1;2]

recherche 4 [1;2]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1=4 || recherche 4 [2]

= recherche 4 [2]

[2] 6= [], x = 2, s = [] ⇒ 2=4 || recherche 4 []

= recherche 4 []

[] = [] ⇒ false

86/103 86

Page 174: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction recherche

Evaluation de recherche 4 [3;2;4;1]

recherche 4 [3;2;4;1]

[3; 2; 4; 1] 6= [], x = 3, s = [2; 4; 1] ⇒ 3=4 || recherche 4 [2;4;1]

= recherche 4 [2;4;1]

[2; 4; 1] 6= [], x = 2, s = [4; 1] ⇒ 2=4 || recherche [4;1]

= recherche 4 [4;1]

[4; 1] 6= [], x = 4, s = [1] ⇒ 4=4 || recherche 4 [1]

= true

Evaluation de recherche 4 [1;2]

recherche 4 [1;2]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1=4 || recherche 4 [2]

= recherche 4 [2]

[2] 6= [], x = 2, s = [] ⇒ 2=4 || recherche 4 []

= recherche 4 []

[] = [] ⇒ false

86/103 86

Page 175: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Longueur d’une liste

La fonction longueur retourne la longueur d’une liste

# let rec longueur l =

match l with

[] -> 0

| _::s -> 1 + (longueur s);;

Une version recursive terminale :

# let longueur l =

let rec longrec acc l =

match l with

[] -> acc

| _::s -> longrec (1+acc) s

in

longrec 0 l

Cette fonction est predefinie en OCAML : List.length

87/103 87

Page 176: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Longueur d’une liste

La fonction longueur retourne la longueur d’une liste

# let rec longueur l =

match l with

[] -> 0

| _::s -> 1 + (longueur s);;

Une version recursive terminale :

# let longueur l =

let rec longrec acc l =

match l with

[] -> acc

| _::s -> longrec (1+acc) s

in

longrec 0 l

Cette fonction est predefinie en OCAML : List.length

87/103 87

Page 177: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Longueur d’une liste

La fonction longueur retourne la longueur d’une liste

# let rec longueur l =

match l with

[] -> 0

| _::s -> 1 + (longueur s);;

Une version recursive terminale :

# let longueur l =

let rec longrec acc l =

match l with

[] -> acc

| _::s -> longrec (1+acc) s

in

longrec 0 l

Cette fonction est predefinie en OCAML : List.length87/103 87

Page 178: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction longueur

Evaluation de longueur [10;2;4]

longueur [10;2;4]

= longrec 0 [10;2;4]

[10; 2; 4] 6= [], s = [2; 4] ⇒ longrec (1+0) [2;4]

[2; 4] 6= [], s = [4] ⇒ longrec (1+1) [4]

[4] 6= [], s = [] ⇒ longrec (1+2) []

[] = [] ⇒ 3

88/103 88

Page 179: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction longueur

Evaluation de longueur [10;2;4]

longueur [10;2;4]

= longrec 0 [10;2;4]

[10; 2; 4] 6= [], s = [2; 4] ⇒ longrec (1+0) [2;4]

[2; 4] 6= [], s = [4] ⇒ longrec (1+1) [4]

[4] 6= [], s = [] ⇒ longrec (1+2) []

[] = [] ⇒ 3

88/103 88

Page 180: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction longueur

Evaluation de longueur [10;2;4]

longueur [10;2;4]

= longrec 0 [10;2;4]

[10; 2; 4] 6= [], s = [2; 4] ⇒ longrec (1+0) [2;4]

[2; 4] 6= [], s = [4] ⇒ longrec (1+1) [4]

[4] 6= [], s = [] ⇒ longrec (1+2) []

[] = [] ⇒ 3

88/103 88

Page 181: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction longueur

Evaluation de longueur [10;2;4]

longueur [10;2;4]

= longrec 0 [10;2;4]

[10; 2; 4] 6= [], s = [2; 4] ⇒ longrec (1+0) [2;4]

[2; 4] 6= [], s = [4] ⇒ longrec (1+1) [4]

[4] 6= [], s = [] ⇒ longrec (1+2) []

[] = [] ⇒ 3

88/103 88

Page 182: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de la fonction longueur

Evaluation de longueur [10;2;4]

longueur [10;2;4]

= longrec 0 [10;2;4]

[10; 2; 4] 6= [], s = [2; 4] ⇒ longrec (1+0) [2;4]

[2; 4] 6= [], s = [4] ⇒ longrec (1+1) [4]

[4] 6= [], s = [] ⇒ longrec (1+2) []

[] = [] ⇒ 3

88/103 88

Page 183: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions polymorphes (1/2)

Quel est le type de la fonction longueur?

longueur doit pouvoir s’appliquer a des listes d’entiers, commepar exemple

# longueur [4;3;6;1;10];;

- : int = 5

. . . alors elle doit avoir le type suivant

val longueur : int list -> int

Mais cette fonction doit aussi pouvoir etre appliquee sur une listedont les elements sont d’un autre type, comme par exemple :

# longueur [[4.5;0.3;9.8];[];[3.2;1.8]];;

- : int = 3

. . . dans ce cas la fonction longueur devrait egalement avoircomme type :

val longueur : (float list) list -> int

89/103 89

Page 184: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions polymorphes (1/2)

Quel est le type de la fonction longueur?

longueur doit pouvoir s’appliquer a des listes d’entiers, commepar exemple

# longueur [4;3;6;1;10];;

- : int = 5

. . . alors elle doit avoir le type suivant

val longueur : int list -> int

Mais cette fonction doit aussi pouvoir etre appliquee sur une listedont les elements sont d’un autre type, comme par exemple :

# longueur [[4.5;0.3;9.8];[];[3.2;1.8]];;

- : int = 3

. . . dans ce cas la fonction longueur devrait egalement avoircomme type :

val longueur : (float list) list -> int

89/103 89

Page 185: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions polymorphes (1/2)

Quel est le type de la fonction longueur?

longueur doit pouvoir s’appliquer a des listes d’entiers, commepar exemple

# longueur [4;3;6;1;10];;

- : int = 5

. . . alors elle doit avoir le type suivant

val longueur : int list -> int

Mais cette fonction doit aussi pouvoir etre appliquee sur une listedont les elements sont d’un autre type, comme par exemple :

# longueur [[4.5;0.3;9.8];[];[3.2;1.8]];;

- : int = 3

. . . dans ce cas la fonction longueur devrait egalement avoircomme type :

val longueur : (float list) list -> int

89/103 89

Page 186: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions polymorphes (1/2)

Quel est le type de la fonction longueur?

longueur doit pouvoir s’appliquer a des listes d’entiers, commepar exemple

# longueur [4;3;6;1;10];;

- : int = 5

. . . alors elle doit avoir le type suivant

val longueur : int list -> int

Mais cette fonction doit aussi pouvoir etre appliquee sur une listedont les elements sont d’un autre type, comme par exemple :

# longueur [[4.5;0.3;9.8];[];[3.2;1.8]];;

- : int = 3

. . . dans ce cas la fonction longueur devrait egalement avoircomme type :

val longueur : (float list) list -> int

89/103 89

Page 187: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions polymorphes (1/2)

Quel est le type de la fonction longueur?

longueur doit pouvoir s’appliquer a des listes d’entiers, commepar exemple

# longueur [4;3;6;1;10];;

- : int = 5

. . . alors elle doit avoir le type suivant

val longueur : int list -> int

Mais cette fonction doit aussi pouvoir etre appliquee sur une listedont les elements sont d’un autre type, comme par exemple :

# longueur [[4.5;0.3;9.8];[];[3.2;1.8]];;

- : int = 3

. . . dans ce cas la fonction longueur devrait egalement avoircomme type :

val longueur : (float list) list -> int

89/103 89

Page 188: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions polymorphes (1/2)

Quel est le type de la fonction longueur?

longueur doit pouvoir s’appliquer a des listes d’entiers, commepar exemple

# longueur [4;3;6;1;10];;

- : int = 5

. . . alors elle doit avoir le type suivant

val longueur : int list -> int

Mais cette fonction doit aussi pouvoir etre appliquee sur une listedont les elements sont d’un autre type, comme par exemple :

# longueur [[4.5;0.3;9.8];[];[3.2;1.8]];;

- : int = 3

. . . dans ce cas la fonction longueur devrait egalement avoircomme type :

val longueur : (float list) list -> int

89/103 89

Page 189: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions polymorphes (2/2)

I Les deux types precedents sont correctsI La fonction longueur a une infinite de types

Le type infere par OCAML est le plus general :

val longueur : ’a list -> int

’a (qui se lit “apostrophe a”, ou encore “alpha”) est une variable detype

Une variable de type veut dire n’importe quel type

Il faut donc lire le type de la fonction longueur comme suit :

“La fonction longueur prend en argument une liste – dont leselements sont de n’importe quel type – et retourne un entier”

90/103 90

Page 190: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions polymorphes (2/2)

I Les deux types precedents sont correctsI La fonction longueur a une infinite de types

Le type infere par OCAML est le plus general :

val longueur : ’a list -> int

’a (qui se lit “apostrophe a”, ou encore “alpha”) est une variable detype

Une variable de type veut dire n’importe quel type

Il faut donc lire le type de la fonction longueur comme suit :

“La fonction longueur prend en argument une liste – dont leselements sont de n’importe quel type – et retourne un entier”

90/103 90

Page 191: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions polymorphes (2/2)

I Les deux types precedents sont correctsI La fonction longueur a une infinite de types

Le type infere par OCAML est le plus general :

val longueur : ’a list -> int

’a (qui se lit “apostrophe a”, ou encore “alpha”) est une variable detype

Une variable de type veut dire n’importe quel type

Il faut donc lire le type de la fonction longueur comme suit :

“La fonction longueur prend en argument une liste – dont leselements sont de n’importe quel type – et retourne un entier”

90/103 90

Page 192: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions polymorphes (2/2)

I Les deux types precedents sont correctsI La fonction longueur a une infinite de types

Le type infere par OCAML est le plus general :

val longueur : ’a list -> int

’a (qui se lit “apostrophe a”, ou encore “alpha”) est une variable detype

Une variable de type veut dire n’importe quel type

Il faut donc lire le type de la fonction longueur comme suit :

“La fonction longueur prend en argument une liste – dont leselements sont de n’importe quel type – et retourne un entier”

90/103 90

Page 193: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Fonctions generiques sur les listes

91/103 91

Page 194: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

concatenation de listes

La fonction append construit une nouvelle la liste en reunissantdeux listes bout a bout

# let rec append l1 l2 =

match l1 with

[] -> l2

| x::s -> x::(append s l2);;

val append : ’a list -> ’a list -> ’a list = <fun>

# append [2;5;1] [10;6;8;15];;

- : int list = [2;5;1;10;6;8;15]

I Cette fonction est predefinie en VERBATIM, il s’agit deList.append

I L’operateur infixe @ est un raccourci syntaxique pour cettefonction, on note l1@l2 la concatenation de l1 et l2

92/103 92

Page 195: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

concatenation de listes

La fonction append construit une nouvelle la liste en reunissantdeux listes bout a bout

# let rec append l1 l2 =

match l1 with

[] -> l2

| x::s -> x::(append s l2);;

val append : ’a list -> ’a list -> ’a list = <fun>

# append [2;5;1] [10;6;8;15];;

- : int list = [2;5;1;10;6;8;15]

I Cette fonction est predefinie en VERBATIM, il s’agit deList.append

I L’operateur infixe @ est un raccourci syntaxique pour cettefonction, on note l1@l2 la concatenation de l1 et l2

92/103 92

Page 196: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de append

Evaluation de append [1;2] [3;4]

append [1;2] [3;4]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1::(append [2] [3;4])

[2] 6= [], x = 2, s = [] ⇒ 1::2::(append [] [3;4])

[] = [] ⇒ 1::2::[3;4]

⇒ 1::[2;3;4]

⇒ [1;2;3;4]

93/103 93

Page 197: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de append

Evaluation de append [1;2] [3;4]

append [1;2] [3;4]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1::(append [2] [3;4])

[2] 6= [], x = 2, s = [] ⇒ 1::2::(append [] [3;4])

[] = [] ⇒ 1::2::[3;4]

⇒ 1::[2;3;4]

⇒ [1;2;3;4]

93/103 93

Page 198: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de append

Evaluation de append [1;2] [3;4]

append [1;2] [3;4]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1::(append [2] [3;4])

[2] 6= [], x = 2, s = [] ⇒ 1::2::(append [] [3;4])

[] = [] ⇒ 1::2::[3;4]

⇒ 1::[2;3;4]

⇒ [1;2;3;4]

93/103 93

Page 199: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de append

Evaluation de append [1;2] [3;4]

append [1;2] [3;4]

[1; 2] 6= [], x = 1, s = [2] ⇒ 1::(append [2] [3;4])

[2] 6= [], x = 2, s = [] ⇒ 1::2::(append [] [3;4])

[] = [] ⇒ 1::2::[3;4]

⇒ 1::[2;3;4]

⇒ [1;2;3;4]

93/103 93

Page 200: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Concatenation rapide

I La fonction append n’est pas recursive terminaleI Si l’ordre des elements n’a pas d’importance, on peut definir

une concatenation recursive terminale qui inverse leselements de la premiere liste

let rec rev_append l1 l2 =

match l1 with

[] -> l2

| x :: s -> rev_append s (x :: l2)

val rev_append : ’a list -> ’a list -> ’a list = <fun>

# rev_append [4;2;6] [1;10;9;5];;

- : int list = [6; 2; 4; 1; 10; 9; 5]

94/103 94

Page 201: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Concatenation rapide

I La fonction append n’est pas recursive terminaleI Si l’ordre des elements n’a pas d’importance, on peut definir

une concatenation recursive terminale qui inverse leselements de la premiere liste

let rec rev_append l1 l2 =

match l1 with

[] -> l2

| x :: s -> rev_append s (x :: l2)

val rev_append : ’a list -> ’a list -> ’a list = <fun>

# rev_append [4;2;6] [1;10;9;5];;

- : int list = [6; 2; 4; 1; 10; 9; 5]

94/103 94

Page 202: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Concatenation rapide

I La fonction append n’est pas recursive terminaleI Si l’ordre des elements n’a pas d’importance, on peut definir

une concatenation recursive terminale qui inverse leselements de la premiere liste

let rec rev_append l1 l2 =

match l1 with

[] -> l2

| x :: s -> rev_append s (x :: l2)

val rev_append : ’a list -> ’a list -> ’a list = <fun>

# rev_append [4;2;6] [1;10;9;5];;

- : int list = [6; 2; 4; 1; 10; 9; 5]

94/103 94

Page 203: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Renverser une liste

La fonction rev pour renverser une liste l s’obtient facilement enconcatenant la liste l avec la liste vide [], en utilisant rev append

# let rev l = rev_append l [];;

val rev : ’a list -> ’a list = <fun>

# rev [4;2;6;1];;

- : int list = [1; 6; 2; 4]

95/103 95

Page 204: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Renverser une liste

La fonction rev pour renverser une liste l s’obtient facilement enconcatenant la liste l avec la liste vide [], en utilisant rev append

# let rev l = rev_append l [];;

val rev : ’a list -> ’a list = <fun>

# rev [4;2;6;1];;

- : int list = [1; 6; 2; 4]

95/103 95

Page 205: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de rev

Evaluation de rev [1;2;3]

rev [1;2;3]

= rev append [1;2;3] []

[1; 2; 3] 6= [], x = 1, s = [2; 3] ⇒ rev append [2;3] (1::[])

= rev append [2;3] [1]

[2; 3] 6= [], x = 2, s = [3] ⇒ rev append [3] (2::[1])

= rev append [3] [2;1]

[3] 6= [], x = 3, s = [] ⇒ rev append [] (3::[2;1])

= rev append [] [3;2;1]

[] = [] ⇒ [3;2;1]

96/103 96

Page 206: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de rev

Evaluation de rev [1;2;3]

rev [1;2;3]

= rev append [1;2;3] []

[1; 2; 3] 6= [], x = 1, s = [2; 3] ⇒ rev append [2;3] (1::[])

= rev append [2;3] [1]

[2; 3] 6= [], x = 2, s = [3] ⇒ rev append [3] (2::[1])

= rev append [3] [2;1]

[3] 6= [], x = 3, s = [] ⇒ rev append [] (3::[2;1])

= rev append [] [3;2;1]

[] = [] ⇒ [3;2;1]

96/103 96

Page 207: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de rev

Evaluation de rev [1;2;3]

rev [1;2;3]

= rev append [1;2;3] []

[1; 2; 3] 6= [], x = 1, s = [2; 3] ⇒ rev append [2;3] (1::[])

= rev append [2;3] [1]

[2; 3] 6= [], x = 2, s = [3] ⇒ rev append [3] (2::[1])

= rev append [3] [2;1]

[3] 6= [], x = 3, s = [] ⇒ rev append [] (3::[2;1])

= rev append [] [3;2;1]

[] = [] ⇒ [3;2;1]

96/103 96

Page 208: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de rev

Evaluation de rev [1;2;3]

rev [1;2;3]

= rev append [1;2;3] []

[1; 2; 3] 6= [], x = 1, s = [2; 3] ⇒ rev append [2;3] (1::[])

= rev append [2;3] [1]

[2; 3] 6= [], x = 2, s = [3] ⇒ rev append [3] (2::[1])

= rev append [3] [2;1]

[3] 6= [], x = 3, s = [] ⇒ rev append [] (3::[2;1])

= rev append [] [3;2;1]

[] = [] ⇒ [3;2;1]

96/103 96

Page 209: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Evaluation de rev

Evaluation de rev [1;2;3]

rev [1;2;3]

= rev append [1;2;3] []

[1; 2; 3] 6= [], x = 1, s = [2; 3] ⇒ rev append [2;3] (1::[])

= rev append [2;3] [1]

[2; 3] 6= [], x = 2, s = [3] ⇒ rev append [3] (2::[1])

= rev append [3] [2;1]

[3] 6= [], x = 3, s = [] ⇒ rev append [] (3::[2;1])

= rev append [] [3;2;1]

[] = [] ⇒ [3;2;1]

96/103 96

Page 210: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recursion terminale

97/103 97

Page 211: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Exemple introductif

Dans un fichier somme.ml :

let rec somme n =

match n with

| 0. -> 0.

| _ -> n +. somme (n -. 1.) ;;

print_float (somme 90000.) ;;

compilation

ocamlc -o somme somme.ml

execution

./somme

Fatal error: exception Stack_overflow

98/103 98

Page 212: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Exemple introductif

Dans un fichier somme.ml :

let rec somme n =

match n with

| 0. -> 0.

| _ -> n +. somme (n -. 1.) ;;

print_float (somme 90000.) ;;

compilation

ocamlc -o somme somme.ml

execution

./somme

Fatal error: exception Stack_overflow

98/103 98

Page 213: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Exemple introductif

Dans un fichier somme.ml :

let rec somme n =

match n with

| 0. -> 0.

| _ -> n +. somme (n -. 1.) ;;

print_float (somme 90000.) ;;

compilation

ocamlc -o somme somme.ml

execution

./somme

Fatal error: exception Stack_overflow

98/103 98

Page 214: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Appels en attente

L’execution du programme precedent devrait correspondre auprocessus d’evaluation suivant

somme 90000.

⇒ 90000. +. somme 89999.

⇒ 90000. +. 89999. +. somme 89998.

⇒ . . .⇒ 90000. +. 89999. +. 4049865001.

⇒ 90000. +. 4049955000.

⇒ 4050045000.

L’appel a somme n est en attente du resultat de l’appel a somme (n-1)

Malheureusement, quand le nombre d’appels en attente est tropgrand le programme s’arrete !

99/103 99

Page 215: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Appels en attente

L’execution du programme precedent devrait correspondre auprocessus d’evaluation suivant

somme 90000.

⇒ 90000. +. somme 89999.

⇒ 90000. +. 89999. +. somme 89998.

⇒ . . .⇒ 90000. +. 89999. +. 4049865001.

⇒ 90000. +. 4049955000.

⇒ 4050045000.

L’appel a somme n est en attente du resultat de l’appel a somme (n-1)

Malheureusement, quand le nombre d’appels en attente est tropgrand le programme s’arrete !

99/103 99

Page 216: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Pile d’appels

Pour executer les appels de fonctions, quelque soit le langage et lecompilateur, on utilise une pile d’appel, dans laquelle on stocke(entre autre) les valeurs des arguments et l’adresse de retour del’appel

La taille de cette pile croıt donc en fonction du nombre d’appels enattente et elle ”deborde” quand il y a trop d’appels en attente(message Stack overflow)

Exemple. sous un Linux standard la taille de la pile est fixee a 8Ko

100/103 100

Page 217: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Appels terminaux

Dans une fonction f, un appel a une fonction g est terminal si leresultat de cet appel est le resultat de f

Exemples :

let f x = g x ;;

let f x = if ... then g x else ... ;;

let f x = if ... then ... else g x ;;

let f x = let y = ... in g y ;;

let f x = match x with ... | p -> g x | ... ;;

Une fonction est recursive terminale si ses appels recursifs sonttous terminaux

101/103 101

Page 218: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Appels terminaux

Dans une fonction f, un appel a une fonction g est terminal si leresultat de cet appel est le resultat de f

Exemples :

let f x = g x ;;

let f x = if ... then g x else ... ;;

let f x = if ... then ... else g x ;;

let f x = let y = ... in g y ;;

let f x = match x with ... | p -> g x | ... ;;

Une fonction est recursive terminale si ses appels recursifs sonttous terminaux

101/103 101

Page 219: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Appels terminaux

Dans une fonction f, un appel a une fonction g est terminal si leresultat de cet appel est le resultat de f

Exemples :

let f x = g x ;;

let f x = if ... then g x else ... ;;

let f x = if ... then ... else g x ;;

let f x = let y = ... in g y ;;

let f x = match x with ... | p -> g x | ... ;;

Une fonction est recursive terminale si ses appels recursifs sonttous terminaux

101/103 101

Page 220: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Appels terminaux

Dans une fonction f, un appel a une fonction g est terminal si leresultat de cet appel est le resultat de f

Exemples :

let f x = g x ;;

let f x = if ... then g x else ... ;;

let f x = if ... then ... else g x ;;

let f x = let y = ... in g y ;;

let f x = match x with ... | p -> g x | ... ;;

Une fonction est recursive terminale si ses appels recursifs sonttous terminaux

101/103 101

Page 221: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Appels terminaux

Dans une fonction f, un appel a une fonction g est terminal si leresultat de cet appel est le resultat de f

Exemples :

let f x = g x ;;

let f x = if ... then g x else ... ;;

let f x = if ... then ... else g x ;;

let f x = let y = ... in g y ;;

let f x = match x with ... | p -> g x | ... ;;

Une fonction est recursive terminale si ses appels recursifs sonttous terminaux

101/103 101

Page 222: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Appels terminaux

Dans une fonction f, un appel a une fonction g est terminal si leresultat de cet appel est le resultat de f

Exemples :

let f x = g x ;;

let f x = if ... then g x else ... ;;

let f x = if ... then ... else g x ;;

let f x = let y = ... in g y ;;

let f x = match x with ... | p -> g x | ... ;;

Une fonction est recursive terminale si ses appels recursifs sonttous terminaux

101/103 101

Page 223: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Execution des appels terminaux

Voici une version de somme recursive terminale

let rec somme_term acc n =

match n with

| 0. -> acc

| _ -> somme_term (n +. acc) (n -. 1.)

;;

let somme n = somme_term 0. n ;;

I Avec cette version plus de debordement de pileI Le compilateur ocamlc traite de maniere speciale les appels

terminaux : il remplace dans la pile d’appel la place occupeepar somme term acc n par l’appel somme term (n +. acc)

( n -. 1.)

102/103 102

Page 224: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Execution des appels terminaux

Voici une version de somme recursive terminale

let rec somme_term acc n =

match n with

| 0. -> acc

| _ -> somme_term (n +. acc) (n -. 1.)

;;

let somme n = somme_term 0. n ;;

I Avec cette version plus de debordement de pileI Le compilateur ocamlc traite de maniere speciale les appels

terminaux : il remplace dans la pile d’appel la place occupeepar somme term acc n par l’appel somme term (n +. acc)

( n -. 1.)

102/103 102

Page 225: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recursion efficace

Programmer avec des accumulateurs

I Principe analogue a l’ajout de variables auxiliaires enprogrammation imperative

I Ajout de fonctions auxiliaires avec des parametressupplementaires, appeles accumulateurs

Autre exemple, la fonction factorielle en version recursive terminale

let rec fact_term acc n =

match n with

| 0 -> acc

| _ -> fact_term (n*acc) (n-1)

;;

let fact n = fact_term 1 n ;;

103/103 103

Page 226: Programmation fonctionnelle avancee´conchon/PFA/manpfa1.pdf · Programmation fonctionnelle avancee´ ... I types de base (int, bool, string, unit) I construction let I appel de fonction

Recursion efficace

Programmer avec des accumulateurs

I Principe analogue a l’ajout de variables auxiliaires enprogrammation imperative

I Ajout de fonctions auxiliaires avec des parametressupplementaires, appeles accumulateurs

Autre exemple, la fonction factorielle en version recursive terminale

let rec fact_term acc n =

match n with

| 0 -> acc

| _ -> fact_term (n*acc) (n-1)

;;

let fact n = fact_term 1 n ;;

103/103 103