Bases de programmation en Caml

publicité
Bases de programmation en Caml
Option informatique 2016-2017
Remarque préliminaire
• Vous êtes amenés à être des spécialistes en informatique,
Remarque préliminaire
• Vous êtes amenés à être des spécialistes en informatique,
• donc vous, vous pouvez apprendre deux langages différents,
Remarque préliminaire
• Vous êtes amenés à être des spécialistes en informatique,
• donc vous, vous pouvez apprendre deux langages différents,
• sans les confondre,
Remarque préliminaire
• Vous êtes amenés à être des spécialistes en informatique,
• donc vous, vous pouvez apprendre deux langages différents,
• sans les confondre,
• ni dans la syntaxe, ni dans leurs particularités.
Remarque préliminaire
• Vous êtes amenés à être des spécialistes en informatique,
• donc vous, vous pouvez apprendre deux langages différents,
• sans les confondre,
• ni dans la syntaxe, ni dans leurs particularités.
• Ce ne sera pas une excuse...
Recommandations d’écriture
• Mettre un espace de part et d’autre de tout opérateur : a = b
Recommandations d’écriture
• Mettre un espace de part et d’autre de tout opérateur : a = b
• Coller la virgule ou le point virgule au terme précédent, et
mettre un espace après : [1; 2; 3]
Recommandations d’écriture
• Mettre un espace de part et d’autre de tout opérateur : a = b
• Coller la virgule ou le point virgule au terme précédent, et
mettre un espace après : [1; 2; 3]
• Coller le terme après la parenthèse/crochet ouvrante et la
parenthèse/crochet fermante au terme précédent : (1, 2, 3)
Recommandations d’écriture
• Mettre un espace de part et d’autre de tout opérateur : a = b
• Coller la virgule ou le point virgule au terme précédent, et
mettre un espace après : [1; 2; 3]
• Coller le terme après la parenthèse/crochet ouvrante et la
parenthèse/crochet fermante au terme précédent : (1, 2, 3)
• Utiliser des noms de variables parlants ;
Recommandations d’écriture
• Mettre un espace de part et d’autre de tout opérateur : a = b
• Coller la virgule ou le point virgule au terme précédent, et
mettre un espace après : [1; 2; 3]
• Coller le terme après la parenthèse/crochet ouvrante et la
parenthèse/crochet fermante au terme précédent : (1, 2, 3)
• Utiliser des noms de variables parlants ;
• Utiliser la possibilité de commenter le code ; (* mon
commentaire *) en Caml ;
Recommandations d’écriture
• Mettre un espace de part et d’autre de tout opérateur : a = b
• Coller la virgule ou le point virgule au terme précédent, et
•
•
•
•
mettre un espace après : [1; 2; 3]
Coller le terme après la parenthèse/crochet ouvrante et la
parenthèse/crochet fermante au terme précédent : (1, 2, 3)
Utiliser des noms de variables parlants ;
Utiliser la possibilité de commenter le code ; (* mon
commentaire *) en Caml ;
Indenter le texte pour la lisibilité (indentation non
significative) ;
Recommandations d’écriture
• Mettre un espace de part et d’autre de tout opérateur : a = b
• Coller la virgule ou le point virgule au terme précédent, et
•
•
•
•
•
mettre un espace après : [1; 2; 3]
Coller le terme après la parenthèse/crochet ouvrante et la
parenthèse/crochet fermante au terme précédent : (1, 2, 3)
Utiliser des noms de variables parlants ;
Utiliser la possibilité de commenter le code ; (* mon
commentaire *) en Caml ;
Indenter le texte pour la lisibilité (indentation non
significative) ;
Tout en minuscules (sauf exception) et sans accent ;
Recommandations d’écriture
• Mettre un espace de part et d’autre de tout opérateur : a = b
• Coller la virgule ou le point virgule au terme précédent, et
•
•
•
•
•
•
mettre un espace après : [1; 2; 3]
Coller le terme après la parenthèse/crochet ouvrante et la
parenthèse/crochet fermante au terme précédent : (1, 2, 3)
Utiliser des noms de variables parlants ;
Utiliser la possibilité de commenter le code ; (* mon
commentaire *) en Caml ;
Indenter le texte pour la lisibilité (indentation non
significative) ;
Tout en minuscules (sauf exception) et sans accent ;
En devoir (et surtout au concours), votre code avec
commentaires et explications sera lu 3 fois au maximum
Recommandations d’écriture
• Mettre un espace de part et d’autre de tout opérateur : a = b
• Coller la virgule ou le point virgule au terme précédent, et
•
•
•
•
•
•
•
mettre un espace après : [1; 2; 3]
Coller le terme après la parenthèse/crochet ouvrante et la
parenthèse/crochet fermante au terme précédent : (1, 2, 3)
Utiliser des noms de variables parlants ;
Utiliser la possibilité de commenter le code ; (* mon
commentaire *) en Caml ;
Indenter le texte pour la lisibilité (indentation non
significative) ;
Tout en minuscules (sauf exception) et sans accent ;
En devoir (et surtout au concours), votre code avec
commentaires et explications sera lu 3 fois au maximum
Si le correcteur ne comprend toujours pas, il passe à la
question suivante...
Types simples
• int : attention au calcul modulo 231 ou 263 .
Types simples
• int : attention au calcul modulo 231 ou 263 .
• float : bien penser à mettre le point partout, dans les
opérateurs (sauf ** ) et dans les nombres ;
Types simples
• int : attention au calcul modulo 231 ou 263 .
• float : bien penser à mettre le point partout, dans les
opérateurs (sauf ** ) et dans les nombres ;
• 1.0 +. 2.0 ou encore 1. +. 2. : Lourd au début, mais
on s’y fait...
Types simples
• int : attention au calcul modulo 231 ou 263 .
• float : bien penser à mettre le point partout, dans les
opérateurs (sauf ** ) et dans les nombres ;
• 1.0 +. 2.0 ou encore 1. +. 2. : Lourd au début, mais
on s’y fait...
• bool : les opérateurs logiques "et" et "ou" sont && (pas and
qui est un mot-clé) et ||
Types simples
• int : attention au calcul modulo 231 ou 263 .
• float : bien penser à mettre le point partout, dans les
opérateurs (sauf ** ) et dans les nombres ;
• 1.0 +. 2.0 ou encore 1. +. 2. : Lourd au début, mais
on s’y fait...
• bool : les opérateurs logiques "et" et "ou" sont && (pas and
qui est un mot-clé) et ||
• Ces opérateurs sont paresseux : évaluation du deuxième
membre uniquement si nécessaire
Types simples
• int : attention au calcul modulo 231 ou 263 .
• float : bien penser à mettre le point partout, dans les
opérateurs (sauf ** ) et dans les nombres ;
• 1.0 +. 2.0 ou encore 1. +. 2. : Lourd au début, mais
on s’y fait...
• bool : les opérateurs logiques "et" et "ou" sont && (pas and
qui est un mot-clé) et ||
• Ces opérateurs sont paresseux : évaluation du deuxième
membre uniquement si nécessaire
• Mais si vous vous appuyez sur cette spécification il est
impératif de le signaler !
Types simples
• char et string : ce sont deux types différents
Types simples
• char et string : ce sont deux types différents
• char entre backquotes (accent grave = ALT-GR 7) : ‘a‘
Types simples
• char et string : ce sont deux types différents
• char entre backquotes (accent grave = ALT-GR 7) : ‘a‘
• string entre double quote : "Bonjour chez vous !"
Types simples
• char et string : ce sont deux types différents
• char entre backquotes (accent grave = ALT-GR 7) : ‘a‘
• string entre double quote : "Bonjour chez vous !"
• n-uplets i.e. produit cartésien (1, "Coucou", true) est de
type int * string * bool
Types simples
• char et string : ce sont deux types différents
• char entre backquotes (accent grave = ALT-GR 7) : ‘a‘
• string entre double quote : "Bonjour chez vous !"
• n-uplets i.e. produit cartésien (1, "Coucou", true) est de
type int * string * bool
• unit : le type vide qui ne contient qu’une seule valeur () .
Pour les fonctions agissant par effet de bord (programmation
impérative)
Phrase
• Caml évalue des phrases qui se terminent par un double
point-virgule ;;
Phrase
• Caml évalue des phrases qui se terminent par un double
point-virgule ;;
• et répond en donnant les trois informations suivantes :
Phrase
• Caml évalue des phrases qui se terminent par un double
point-virgule ;;
• et répond en donnant les trois informations suivantes :
• le nom de la variable globale qui vient d’être définie le cas
échéant ou, à défaut, un simple tiret.
Phrase
• Caml évalue des phrases qui se terminent par un double
point-virgule ;;
• et répond en donnant les trois informations suivantes :
• le nom de la variable globale qui vient d’être définie le cas
échéant ou, à défaut, un simple tiret.
• le type du résultat.
Phrase
• Caml évalue des phrases qui se terminent par un double
point-virgule ;;
• et répond en donnant les trois informations suivantes :
• le nom de la variable globale qui vient d’être définie le cas
échéant ou, à défaut, un simple tiret.
• le type du résultat.
• la valeur du résultat.
Phrase
• Caml évalue des phrases qui se terminent par un double
point-virgule ;;
• et répond en donnant les trois informations suivantes :
• le nom de la variable globale qui vient d’être définie le cas
échéant ou, à défaut, un simple tiret.
• le type du résultat.
• la valeur du résultat.
• nom : type = valeur ou - : type = valeur
Liaisons globales
• Liaison globale par let : let a = 3;;
Liaisons globales
• Liaison globale par let : let a = 3;;
• Ne crée pas une variable qu’on peut mettre à jour !
Liaisons globales
• Liaison globale par let : let a = 3;;
• Ne crée pas une variable qu’on peut mettre à jour !
• let a = 5;; crée une nouvelle liaison. La précédente est
perdue
Liaisons globales
• Liaison globale par let : let a = 3;;
• Ne crée pas une variable qu’on peut mettre à jour !
• let a = 5;; crée une nouvelle liaison. La précédente est
perdue
• la liaison est statique.
Liaisons globales
• Liaison globale par let : let a = 3;;
• Ne crée pas une variable qu’on peut mettre à jour !
• let a = 5;; crée une nouvelle liaison. La précédente est
perdue
• la liaison est statique.
• let b = a;; b ne sera pas changé si plus tard on fait une
nouvelle liaison avec l’identificateur a
Liaisons locales
• Liaison locale par let... in : let a = 3 in a * a ; ;
Liaisons locales
• Liaison locale par let... in : let a = 3 in a * a ; ;
• N’existe que dans l’expression suivant le in
Liaisons locales
• Liaison locale par let... in : let a = 3 in a * a ; ;
• N’existe que dans l’expression suivant le in
• Ne peut utiliser que des liaisons déjà connues
Liaisons locales
• Liaison locale par let... in : let a = 3 in a * a ; ;
• N’existe que dans l’expression suivant le in
• Ne peut utiliser que des liaisons déjà connues
• Peuvent s’imbriquer let... in let ... in let ... in
...
Liaisons locales
• Liaison locale par let... in : let a = 3 in a * a ; ;
• N’existe que dans l’expression suivant le in
• Ne peut utiliser que des liaisons déjà connues
• Peuvent s’imbriquer let... in let ... in let ... in
...
• Liaisons simultanées (en parallèle) avec and
Liaisons locales
• Liaison locale par let... in : let a = 3 in a * a ; ;
• N’existe que dans l’expression suivant le in
• Ne peut utiliser que des liaisons déjà connues
• Peuvent s’imbriquer let... in let ... in let ... in
...
• Liaisons simultanées (en parallèle) avec and
• let a = 3 and b = 5 in a * b ; ;
Liaisons locales
• Ceci calcule quelque chose, c’est une expression qui a une
valeur et un type :
Liaisons locales
• Ceci calcule quelque chose, c’est une expression qui a une
valeur et un type :
• - : int = 15
Liaisons locales
• Ceci calcule quelque chose, c’est une expression qui a une
valeur et un type :
• - : int = 15
• Contrairement à la liaison globale qui n’est pas une expression
Liaisons locales
• Ceci calcule quelque chose, c’est une expression qui a une
valeur et un type :
• - : int = 15
• Contrairement à la liaison globale qui n’est pas une expression
•
1 let x = let a = 2 in a * a ;;
Est autorisé
Liaisons locales
• Ceci calcule quelque chose, c’est une expression qui a une
valeur et un type :
• - : int = 15
• Contrairement à la liaison globale qui n’est pas une expression
•
1 let x = let a = 2 in a * a ;;
Est autorisé
•
1 let a = 2 in let x = a * a ;;
Ne l’est pas !
Caml est fortement typé
• Caml analyse toutes les expressions avant de les évaluer
Caml est fortement typé
• Caml analyse toutes les expressions avant de les évaluer
• et infère leur type
Caml est fortement typé
• Caml analyse toutes les expressions avant de les évaluer
• et infère leur type
• Il s’assure ainsi que les fonctions et les opérateurs sont utilisés
avec les objets du bon type
Caml est fortement typé
• Caml analyse toutes les expressions avant de les évaluer
• et infère leur type
• Il s’assure ainsi que les fonctions et les opérateurs sont utilisés
avec les objets du bon type
• C’est contraignant parfois, mais c’est une énorme gage de
sécurité à l’exécution.
Caml est fortement typé
• Caml analyse toutes les expressions avant de les évaluer
• et infère leur type
• Il s’assure ainsi que les fonctions et les opérateurs sont utilisés
avec les objets du bon type
• C’est contraignant parfois, mais c’est une énorme gage de
sécurité à l’exécution.
• Il faudra apprendre à déterminer, comme Caml , le type des
expressions (exercices)
Caml est fortement typé
• Caml analyse toutes les expressions avant de les évaluer
• et infère leur type
• Il s’assure ainsi que les fonctions et les opérateurs sont utilisés
avec les objets du bon type
• C’est contraignant parfois, mais c’est une énorme gage de
sécurité à l’exécution.
• Il faudra apprendre à déterminer, comme Caml , le type des
expressions (exercices)
• Il n’y a pas de conversion implicite entre types
Caml est fortement typé
• Caml analyse toutes les expressions avant de les évaluer
• et infère leur type
• Il s’assure ainsi que les fonctions et les opérateurs sont utilisés
avec les objets du bon type
• C’est contraignant parfois, mais c’est une énorme gage de
sécurité à l’exécution.
• Il faudra apprendre à déterminer, comme Caml , le type des
expressions (exercices)
• Il n’y a pas de conversion implicite entre types
• 3 + 4. est interdit !
Caml est fortement typé
• Caml analyse toutes les expressions avant de les évaluer
• et infère leur type
• Il s’assure ainsi que les fonctions et les opérateurs sont utilisés
avec les objets du bon type
• C’est contraignant parfois, mais c’est une énorme gage de
sécurité à l’exécution.
• Il faudra apprendre à déterminer, comme Caml , le type des
expressions (exercices)
• Il n’y a pas de conversion implicite entre types
• 3 + 4. est interdit !
• Si nécessaire il existe des fonctions de conversion explicites
Caml est fortement typé
• Caml analyse toutes les expressions avant de les évaluer
• et infère leur type
• Il s’assure ainsi que les fonctions et les opérateurs sont utilisés
avec les objets du bon type
• C’est contraignant parfois, mais c’est une énorme gage de
sécurité à l’exécution.
• Il faudra apprendre à déterminer, comme Caml , le type des
expressions (exercices)
• Il n’y a pas de conversion implicite entre types
• 3 + 4. est interdit !
• Si nécessaire il existe des fonctions de conversion explicites
• int_of_float, string_of_char,...
Fonctions d’une seule variable
• Déclaration : let f x = ...
Fonctions d’une seule variable
• Déclaration : let f x = ...
• let f x = x * x;;
Fonctions d’une seule variable
• Déclaration : let f x = ...
• let f x = x * x;;
• f : int -> int = <fun>
Fonctions d’une seule variable
• Déclaration : let f x = ...
• let f x = x * x;;
• f : int -> int = <fun>
• Utilisation f (3);; voire f 3;; (parenthèses inutiles ici)
Fonctions d’une seule variable
• Déclaration : let f x = ...
• let f x = x * x;;
• f : int -> int = <fun>
• Utilisation f (3);; voire f 3;; (parenthèses inutiles ici)
• Attention les appels de fonction sont associés à gauche
Fonctions d’une seule variable
• Déclaration : let f x = ...
• let f x = x * x;;
• f : int -> int = <fun>
• Utilisation f (3);; voire f 3;; (parenthèses inutiles ici)
• Attention les appels de fonction sont associés à gauche
• pour calculer f (f (3)) il faut écrire f (f 3);;
Fonctions d’une seule variable
• Déclaration : let f x = ...
• let f x = x * x;;
• f : int -> int = <fun>
• Utilisation f (3);; voire f 3;; (parenthèses inutiles ici)
• Attention les appels de fonction sont associés à gauche
• pour calculer f (f (3)) il faut écrire f (f 3);;
• f f 3;; provoque une erreur
Fonctions d’une seule variable
• Déclaration : let f x = ...
• let f x = x * x;;
• f : int -> int = <fun>
• Utilisation f (3);; voire f 3;; (parenthèses inutiles ici)
• Attention les appels de fonction sont associés à gauche
• pour calculer f (f (3)) il faut écrire f (f 3);;
• f f 3;; provoque une erreur
• Les opérateurs algébriques gardent cependant la préséance
Fonctions d’une seule variable
• Déclaration : let f x = ...
• let f x = x * x;;
• f : int -> int = <fun>
• Utilisation f (3);; voire f 3;; (parenthèses inutiles ici)
• Attention les appels de fonction sont associés à gauche
• pour calculer f (f (3)) il faut écrire f (f 3);;
• f f 3;; provoque une erreur
• Les opérateurs algébriques gardent cependant la préséance
• pour calculer f (3) + f (3) on peut écrire f 3 + f 3;;
Fonctions d’une seule variable
• Déclaration : let f x = ...
• let f x = x * x;;
• f : int -> int = <fun>
• Utilisation f (3);; voire f 3;; (parenthèses inutiles ici)
• Attention les appels de fonction sont associés à gauche
• pour calculer f (f (3)) il faut écrire f (f 3);;
• f f 3;; provoque une erreur
• Les opérateurs algébriques gardent cependant la préséance
• pour calculer f (3) + f (3) on peut écrire f 3 + f 3;;
• En cas de doute : parenthésez vos expressions !
Fonction de plusieurs variables
• Plusieurs solutions
Fonction de plusieurs variables
• Plusieurs solutions
• En faire une fonction à une seule variable qui soit un n-uplet.
Fonction de plusieurs variables
• Plusieurs solutions
• En faire une fonction à une seule variable qui soit un n-uplet.
• Par exemple let produit1 (x, y) = x * y;;
Fonction de plusieurs variables
• Plusieurs solutions
• En faire une fonction à une seule variable qui soit un n-uplet.
• Par exemple let produit1 (x, y) = x * y;;
• crée une fonction de type int * int -> int
Fonction de plusieurs variables
• Plusieurs solutions
• En faire une fonction à une seule variable qui soit un n-uplet.
• Par exemple let produit1 (x, y) = x * y;;
• crée une fonction de type int * int -> int
• Autre solution séparer les arguments par un simple espace
Fonction de plusieurs variables
• Plusieurs solutions
• En faire une fonction à une seule variable qui soit un n-uplet.
• Par exemple let produit1 (x, y) = x * y;;
• crée une fonction de type int * int -> int
• Autre solution séparer les arguments par un simple espace
• let produit2 x y = x * y;;
Fonction de plusieurs variables
• Plusieurs solutions
• En faire une fonction à une seule variable qui soit un n-uplet.
• Par exemple let produit1 (x, y) = x * y;;
• crée une fonction de type int * int -> int
• Autre solution séparer les arguments par un simple espace
• let produit2 x y = x * y;;
• crée une fonction de type int -> int -> int
Fonction de plusieurs variables
• Plusieurs solutions
• En faire une fonction à une seule variable qui soit un n-uplet.
• Par exemple let produit1 (x, y) = x * y;;
• crée une fonction de type int * int -> int
• Autre solution séparer les arguments par un simple espace
• let produit2 x y = x * y;;
• crée une fonction de type int -> int -> int
• Noter la différence de type qu’il faut savoir interpréter
Fonction de plusieurs variables
• La première forme est dite non curryfiée
Fonction de plusieurs variables
• La première forme est dite non curryfiée
• La seconde est la forme curryfiée
Fonction de plusieurs variables
• La première forme est dite non curryfiée
• La seconde est la forme curryfiée
• Elle nous dit que produit2 est une fonction qui à un entier
associe une fonction
Fonction de plusieurs variables
• La première forme est dite non curryfiée
• La seconde est la forme curryfiée
• Elle nous dit que produit2 est une fonction qui à un entier
associe une fonction
• qui à un entier associe un entier !
Fonction de plusieurs variables
• La première forme est dite non curryfiée
• La seconde est la forme curryfiée
• Elle nous dit que produit2 est une fonction qui à un entier
associe une fonction
• qui à un entier associe un entier !
• Ainsi produit2 3;; est la fonction : y → 3 ∗ y
Fonction de plusieurs variables
• La première forme est dite non curryfiée
• La seconde est la forme curryfiée
• Elle nous dit que produit2 est une fonction qui à un entier
associe une fonction
• qui à un entier associe un entier !
• Ainsi produit2 3;; est la fonction : y → 3 ∗ y
• C’est ce qu’on appelle une fonction partielle.
Fonction anonyme
• On peut créer une fonction à une seule variable sans nom par
le mot clé function
Fonction anonyme
• On peut créer une fonction à une seule variable sans nom par
le mot clé function
• function x -> x * x;; est une fonction avec la même
fonctionnalité que f , mais sans nom !
Fonction anonyme
• On peut créer une fonction à une seule variable sans nom par
le mot clé function
• function x -> x * x;; est une fonction avec la même
fonctionnalité que f , mais sans nom !
• Peut être utile dans certains cas où on ne veut pas créer une
liaison vers la fonction, mais simplement la passer en
paramètre
Fonction anonyme
• On peut créer une fonction à une seule variable sans nom par
le mot clé function
• function x -> x * x;; est une fonction avec la même
fonctionnalité que f , mais sans nom !
• Peut être utile dans certains cas où on ne veut pas créer une
liaison vers la fonction, mais simplement la passer en
paramètre
• On peut bien sûr aussi lier la fonction à un identifiant avec
let : let f = function x -> x * x;;
Fonction anonyme
• On peut créer une fonction à une seule variable sans nom par
le mot clé function
• function x -> x * x;; est une fonction avec la même
fonctionnalité que f , mais sans nom !
• Peut être utile dans certains cas où on ne veut pas créer une
liaison vers la fonction, mais simplement la passer en
paramètre
• On peut bien sûr aussi lier la fonction à un identifiant avec
let : let f = function x -> x * x;;
• Pour les fonctions à plusieurs variables on utilise fun (en
forme curryfiée forcément...)
Fonction anonyme
• On peut créer une fonction à une seule variable sans nom par
le mot clé function
• function x -> x * x;; est une fonction avec la même
fonctionnalité que f , mais sans nom !
• Peut être utile dans certains cas où on ne veut pas créer une
liaison vers la fonction, mais simplement la passer en
paramètre
• On peut bien sûr aussi lier la fonction à un identifiant avec
let : let f = function x -> x * x;;
• Pour les fonctions à plusieurs variables on utilise fun (en
forme curryfiée forcément...)
• fun x y -> x * y;; a la même fonctionnalité que
produit2 mais sans nom !
Fonctions
• Les fonctions sont des valeurs comme les autres
Fonctions
• Les fonctions sont des valeurs comme les autres
• typées
Fonctions
• Les fonctions sont des valeurs comme les autres
• typées
• Peuvent être calculées, passées en paramètre, renvoyées par
une fonction...
Fonctions
• Les fonctions sont des valeurs comme les autres
• typées
• Peuvent être calculées, passées en paramètre, renvoyées par
une fonction...
• typage associatif à droite, c’est-à-dire que
Fonctions
• Les fonctions sont des valeurs comme les autres
• typées
• Peuvent être calculées, passées en paramètre, renvoyées par
une fonction...
• typage associatif à droite, c’est-à-dire que
• int -> (int -> (int -> int)) est équivalent à
Fonctions
• Les fonctions sont des valeurs comme les autres
• typées
• Peuvent être calculées, passées en paramètre, renvoyées par
une fonction...
• typage associatif à droite, c’est-à-dire que
• int -> (int -> (int -> int)) est équivalent à
• int -> int -> int -> int . Caml fera la simplification d’ailleurs
Filtrage par motif (pattern matching)
• C’est un trait extrêmement puissant de Caml ;
Filtrage par motif (pattern matching)
• C’est un trait extrêmement puissant de Caml ;
• qui permet de faire des calculs (et définir des fonctions) par
cas distincts ;
Filtrage par motif (pattern matching)
• C’est un trait extrêmement puissant de Caml ;
• qui permet de faire des calculs (et définir des fonctions) par
cas distincts ;
• une première syntaxe :
1
2
3
4
5
match expr0 with
| motif1 -> expr1
| motif2 -> expr2
| ..............
| motifn -> exprn ;;
Filtrage par motif (pattern matching)
• C’est un trait extrêmement puissant de Caml ;
• qui permet de faire des calculs (et définir des fonctions) par
cas distincts ;
• une première syntaxe :
1
2
3
4
5
match expr0 with
| motif1 -> expr1
| motif2 -> expr2
| ..............
| motifn -> exprn ;;
• L’expression expr0 est évaluée, et sa valeur comparée au
premier motif :
Filtrage par motif (pattern matching)
• C’est un trait extrêmement puissant de Caml ;
• qui permet de faire des calculs (et définir des fonctions) par
cas distincts ;
• une première syntaxe :
1
2
3
4
5
match expr0 with
| motif1 -> expr1
| motif2 -> expr2
| ..............
| motifn -> exprn ;;
• L’expression expr0 est évaluée, et sa valeur comparée au
premier motif :
• si cette valeur répond aux contraintes du motif, c’est
expr1 qui sera évaluée en réponse au filtrage ;
Filtrage par motif (pattern matching)
• C’est un trait extrêmement puissant de Caml ;
• qui permet de faire des calculs (et définir des fonctions) par
cas distincts ;
• une première syntaxe :
1
2
3
4
5
match expr0 with
| motif1 -> expr1
| motif2 -> expr2
| ..............
| motifn -> exprn ;;
• L’expression expr0 est évaluée, et sa valeur comparée au
premier motif :
• si cette valeur répond aux contraintes du motif, c’est
expr1 qui sera évaluée en réponse au filtrage ;
• sinon, sa valeur est comparée au second motif, et ainsi de
suite...
Filtrage par motif (pattern matching)
• C’est un trait extrêmement puissant de Caml ;
• qui permet de faire des calculs (et définir des fonctions) par
cas distincts ;
• une première syntaxe :
1
2
3
4
5
match expr0 with
| motif1 -> expr1
| motif2 -> expr2
| ..............
| motifn -> exprn ;;
• L’expression expr0 est évaluée, et sa valeur comparée au
premier motif :
• si cette valeur répond aux contraintes du motif, c’est
expr1 qui sera évaluée en réponse au filtrage ;
• sinon, sa valeur est comparée au second motif, et ainsi de
suite...
• Si aucun motif n’est reconnu, une exception
Match_failure est levée.
Filtrage par motif (pattern matching)
• Une autre syntaxe possible avec function
1
2
3
4
5
let f = function
| motif1 -> expr1
| motif2 -> expr2
| ..............
| motifn -> exprn ;;
Filtrage par motif (pattern matching)
• Une autre syntaxe possible avec function
1
2
3
4
5
let f = function
| motif1 -> expr1
| motif2 -> expr2
| ..............
| motifn -> exprn ;;
• Par exemple
1 # let sinc = function
2
| 0. -> 1.
3
| x -> sin ( x ) /. x ;;
4 sinc : float -> float = <fun>
Filtrage par motif (pattern matching)
• Une autre syntaxe possible avec function
1
2
3
4
5
let f = function
| motif1 -> expr1
| motif2 -> expr2
| ..............
| motifn -> exprn ;;
• Par exemple
1 # let sinc = function
2
| 0. -> 1.
3
| x -> sin ( x ) /. x ;;
4 sinc : float -> float = <fun>
• Noter que l’argument de la fonction n’est pas nommé juste
après function , mais qu’on peut utiliser le nom du motif
pour le calcul
Filtrage par motif (pattern matching)
• Il existe un motif particulier _ (sous la touche 8) qui
correspond à toute valeur :
Filtrage par motif (pattern matching)
• Il existe un motif particulier _ (sous la touche 8) qui
correspond à toute valeur :
• Par exemple
1 # let est_nul n = match n with
2
| 0 -> true
3
| _ -> false ;;
4 est_nul : int -> bool = <fun>
Filtrage gardé
• On ne peut pas forcément tout contraindre par un motif. On
peut alors utiliser une condition supplémentaire : une garde
Filtrage gardé
• On ne peut pas forcément tout contraindre par un motif. On
peut alors utiliser une condition supplémentaire : une garde
• syntaxe | motif
when
condition ->
Filtrage gardé
• On ne peut pas forcément tout contraindre par un motif. On
peut alors utiliser une condition supplémentaire : une garde
• syntaxe | motif
when
condition ->
• Par exemple
1 # let est_pair n = match n with
2
| m when m mod 2 = 0 -> true
3
| _ -> false ;;
4 est_pair : int -> bool = <fun>
Filtrage gardé
• On ne peut pas utiliser un identificateur déjà utilisé dans un
motif...
1
2
3
4
5
6
7
8
9
10
# let egal y x = match y with
| x -> true
| _ -> false ;;
Entrée interactive :
> | _ -> false ;;
>
ˆ
Attention ! ce cas de filtrage est inutilie.
egal : ’a -> ’b -> bool = <fun>
# egal 1 " artichaut " ;;
egal : bool = true
Filtrage gardé
• On ne peut pas utiliser un identificateur déjà utilisé dans un
motif...
1
2
3
4
5
6
7
8
9
10
# let egal y x = match y with
| x -> true
| _ -> false ;;
Entrée interactive :
> | _ -> false ;;
>
ˆ
Attention ! ce cas de filtrage est inutilie.
egal : ’a -> ’b -> bool = <fun>
# egal 1 " artichaut " ;;
egal : bool = true
• le deuxième x est un motif, ce n’est pas la valeur reçue en
paramètre !
Filtrage gardé
• Solution : on utilise aussi une garde
1 # let egal y x = match y with
2
| y when y = x -> true
3
| _ -> false ;;
4 egal : ’a -> ’a -> bool = <fun>
Polymorphisme
• Parfois certaines fonctions peuvent s’appliquer à un type
quelconque (cf. la fonction egal ci-dessus) ;
Polymorphisme
• Parfois certaines fonctions peuvent s’appliquer à un type
quelconque (cf. la fonction egal ci-dessus) ;
• Ces fonctions sont dites polymorphes ;
Polymorphisme
• Parfois certaines fonctions peuvent s’appliquer à un type
quelconque (cf. la fonction egal ci-dessus) ;
• Ces fonctions sont dites polymorphes ;
• Caml utilise alors un type inconnu ’a , puis ’b s’il y en a
besoin d’un autre...etc..
Polymorphisme
• Parfois certaines fonctions peuvent s’appliquer à un type
quelconque (cf. la fonction egal ci-dessus) ;
• Ces fonctions sont dites polymorphes ;
• Caml utilise alors un type inconnu ’a , puis ’b s’il y en a
besoin d’un autre...etc..
• Par exemple il existe deux fonctions fst et snd qui rendent
respectivement le premier élément et le second élément d’un
couple (2-uplet)
1
2
3
4
fst ;;
fst : ’a * ’b -> ’a = <fun>
snd ;;
snd : ’a * ’b -> ’b = <fun>
Programmation fonctionnelle
• Le paradigme : on ne définit que des fonctions au sens
mathématiques ;
Programmation fonctionnelle
• Le paradigme : on ne définit que des fonctions au sens
mathématiques ;
• un programme est alors une succession d’appels de fonctions
Programmation fonctionnelle
• Le paradigme : on ne définit que des fonctions au sens
mathématiques ;
• un programme est alors une succession d’appels de fonctions
• Cela interdit l’utilisation de variables, de boucles for, de
boucles while,...
Programmation fonctionnelle
• Le paradigme : on ne définit que des fonctions au sens
mathématiques ;
• un programme est alors une succession d’appels de fonctions
• Cela interdit l’utilisation de variables, de boucles for, de
boucles while,...
• qui relèvent de la programmation dite impérative
Programmation fonctionnelle
• Le paradigme : on ne définit que des fonctions au sens
mathématiques ;
• un programme est alors une succession d’appels de fonctions
• Cela interdit l’utilisation de variables, de boucles for, de
boucles while,...
• qui relèvent de la programmation dite impérative
• Caml n’est pas entièrement un langage fonctionnel et
propose la possibilité de programmer impérativement même
s’il n’est pas vraiment conçu pour cela
Programmation fonctionnelle
• Dans un premier temps on ne fera que de la programmation
fonctionnelle
Programmation fonctionnelle
• Dans un premier temps on ne fera que de la programmation
fonctionnelle
• Cela impose un nouveau type d’approche
Programmation fonctionnelle
• Dans un premier temps on ne fera que de la programmation
fonctionnelle
• Cela impose un nouveau type d’approche
• et en particulier il peut être nécessaire voire indispensable
qu’une fonction puisse s’appeler elle-même
Programmation fonctionnelle
• Dans un premier temps on ne fera que de la programmation
fonctionnelle
• Cela impose un nouveau type d’approche
• et en particulier il peut être nécessaire voire indispensable
qu’une fonction puisse s’appeler elle-même
• Ceci relève du domaine de la récursivité
Programmation fonctionnelle
• Dans un premier temps on ne fera que de la programmation
fonctionnelle
• Cela impose un nouveau type d’approche
• et en particulier il peut être nécessaire voire indispensable
qu’une fonction puisse s’appeler elle-même
• Ceci relève du domaine de la récursivité
• que nous allons tout de suite utiliser
Programmation fonctionnelle
• Dans un premier temps on ne fera que de la programmation
fonctionnelle
• Cela impose un nouveau type d’approche
• et en particulier il peut être nécessaire voire indispensable
qu’une fonction puisse s’appeler elle-même
• Ceci relève du domaine de la récursivité
• que nous allons tout de suite utiliser
• et dont nous étudierons les aspects théoriques sous peu.
Récursivité
• Pour qu’une fonction puisse s’appeler elle-même il faut utiliser
le mot clé rec après le let
1 # let rec fact n =
2
match n with
3
| 0 -> 1
4
| _ -> n * fact ( n - 1) ;;
5 fact : int -> int = <fun>
Récursivité
• Pour qu’une fonction puisse s’appeler elle-même il faut utiliser
le mot clé rec après le let
1 # let rec fact n =
2
match n with
3
| 0 -> 1
4
| _ -> n * fact ( n - 1) ;;
5 fact : int -> int = <fun>
• Noter la structure (on verra que c’est général), de manière à
ce que la succession d’appels s’arrête
Récursivité
• Pour qu’une fonction puisse s’appeler elle-même il faut utiliser
le mot clé rec après le let
1 # let rec fact n =
2
match n with
3
| 0 -> 1
4
| _ -> n * fact ( n - 1) ;;
5 fact : int -> int = <fun>
• Noter la structure (on verra que c’est général), de manière à
ce que la succession d’appels s’arrête
• il y a filtrage
Récursivité
• Pour qu’une fonction puisse s’appeler elle-même il faut utiliser
le mot clé rec après le let
1 # let rec fact n =
2
match n with
3
| 0 -> 1
4
| _ -> n * fact ( n - 1) ;;
5 fact : int -> int = <fun>
• Noter la structure (on verra que c’est général), de manière à
ce que la succession d’appels s’arrête
• il y a filtrage
• le(s) premier(s) motif(s) corresponde(nt) aux cas dits de base,
pour lequel on connaît la réponse sans calcul
Récursivité
• Pour qu’une fonction puisse s’appeler elle-même il faut utiliser
le mot clé rec après le let
1 # let rec fact n =
2
match n with
3
| 0 -> 1
4
| _ -> n * fact ( n - 1) ;;
5 fact : int -> int = <fun>
• Noter la structure (on verra que c’est général), de manière à
ce que la succession d’appels s’arrête
• il y a filtrage
• le(s) premier(s) motif(s) corresponde(nt) aux cas dits de base,
pour lequel on connaît la réponse sans calcul
• ensuite on trouve la traduction de la relation de récurrence
n! = n × (n − 1)!
Récursivité
• Pour qu’une fonction puisse s’appeler elle-même il faut utiliser
le mot clé rec après le let
1 # let rec fact n =
2
match n with
3
| 0 -> 1
4
| _ -> n * fact ( n - 1) ;;
5 fact : int -> int = <fun>
• Noter la structure (on verra que c’est général), de manière à
ce que la succession d’appels s’arrête
• il y a filtrage
• le(s) premier(s) motif(s) corresponde(nt) aux cas dits de base,
pour lequel on connaît la réponse sans calcul
• ensuite on trouve la traduction de la relation de récurrence
n! = n × (n − 1)!
• Les appels se font successivement avec des valeurs de n
strictement décroissante, ce qui fait qu’on finira par un (le) cas
de base.
Récursivité
• On peut définir plusieurs fonctions mutuellement récursives
avec le mot clé and :
1 # let rec f n = match n with
2
| 0 -> ...
3
| _ -> ...
4
and g n = match n with
5
| 0 -> ...
6
| _ -> ... ;;
7 f : int -> int = <fun>
8 g : int -> int = <fun>
Récursivité
• On peut définir plusieurs fonctions mutuellement récursives
avec le mot clé and :
1 # let rec f n = match n with
2
| 0 -> ...
3
| _ -> ...
4
and g n = match n with
5
| 0 -> ...
6
| _ -> ... ;;
7 f : int -> int = <fun>
8 g : int -> int = <fun>
• Difficulté du changement de paradigme : il va falloir arriver à
penser récursif... (exercices)
Gestion des erreurs
• À notre niveau si on veut signaler une erreur dans l’utilisation
d’une fonction
Gestion des erreurs
• À notre niveau si on veut signaler une erreur dans l’utilisation
d’une fonction
• on lèvera une exception avec l’instructiion failwith
1 # let divise x y = match y with
2
| 0. -> failwith " Division par z é ro
interdite ! "
3
| _ -> x /. y ;;
4 divise : float -> float -> float
Téléchargement