Académique Documents
Professionnel Documents
Culture Documents
abstraction concrète
Une session Caml correspond à une boucle dans laquelle une lecture d'expressions est réalisée sur l'unité d'entrée
standard, chaque expression lue est soumise à une analyse lexicale puis à une analyse syntaxique, ensuite elle est
typée par le système d'inférence de types, avec affichage du type inféré, et pour terminer, évaluée avec affichage de
.la valeur obtenue en résultat
Exemple de session Caml Light
Au démarrage, le système interactif affiche la version de Caml Light active, suivie de l'invite "#" qui indique que le
système est en attente d'une entrée de l'opérateur
Caml Light version 0.71 >
#
à ce moment, si l'opérateur veut évaluer une expression telle que "12 + 35", il entre l'expression en la terminant
";;" par un double point-virgule
Caml Light version 0.71 >
;; 35 + #12
pour valider et transmettre l'expression au système interactif, il frappe la touche d'entrée dite retour chariot ou [CR].
A la suite de quoi, le système interactif effectue et affiche le typage et l'évaluation de l'expression. Ceci fait, le
.système affiche l'invite et se place, de nouveau, en attente
Caml Light version 0.71 >
[CR] ;; 35 + #12
int = 17 : -
#
Le cycle : nouvelle entrée -> typage-évaluation -> affichage -> nouvelle entrée, se poursuit jusqu'à ce que
.)(l'opérateur termine la session en entrant la commande quit
Caml Light version 0.71 >
[CR] ;; 35 + #12
int = 17 : -
......#
.......
[quit() ;; [CR#
.Au cours d'une session Caml, l'environnement global est modifié par les déclarations globales
Pour construire un programme sous le système interactif, il suffit de déclarer les types, exceptions, constantes,
.variables et fonctions qui seront aussitôt évaluées et introduites dans l'environnement de travail
On peut construire un fichier texte contenant la séquence des déclarations. Il suffit, alors, d'appeler ce fichier par la
.commande include pour retrouver l'environnement de travail ainsi défini
Il est aussi possible de charger le fichier source, avec la commande load, ou compilé, avec la commande
load_object. De cette façon il sera possible de retrouver l'environnemnt de travail au moyen de la directive #open
mais aussi de le libérer, au moyen de la directive #close
Charger un programme
La fonction include
La fonction load
La fonction load_object
La directive #open
: Trois commandes sont utilisées pour charger les fichiers de modules Caml
.(Les fonctions include et load pour charger les fichiers sources des modules (texte Caml•
.La fonction load pour charger les fichiers compilés des modules•
.La directive #open sert à ouvrir les modules chargés
let bits_of_char c =
let c' = int_of_char c
in
it_list (fun l i -> (c' lsr i) land 1 :: l)
[] (intervalle 0 7) ;;
let bits_of_string s =
list_it
(fun i l -> bits_of_char s.[i] @ l)
(intervalle 0 (string_length s - 1))
[0;0;0;0;0;0;0;0] ;;
let recherche a s =
let rec aux l = function
| Feuille s' -> s = s'
| Nud(k,g,d)
-> try
let t :: q = skip k l
in
aux q (if t = 0 then g else d)
with _ -> false
in
aux (bits_of_string s) a ;;
let trouve_place s a =
let rec descend = function
| Feuille s' -> s'
| Nud(_,g,_) -> descend g
in
let rec aux l = function
| Feuille s' -> s'
| Nud(k,g,d)
-> try
match skip k l with
t :: q -> aux q (if t = 0 then g else d)
with _ -> descend g
in
aux (bits_of_string s) a ;;
let insertion a s =
let s' = trouve_place s a
in
if s = s' then a
else
let l,l' = (bits_of_string s),(bits_of_string s')
in
let i,c,_ = discrimine l l' 0
in
let rec aux j l = function
| Feuille s' as a
-> if c = 0 then Nud(j,Feuille s,a)
else Nud(j,a,Feuille s)
| Nud(k,g,d) as a
-> if j > k then
let t :: q = skip k l
in
if t = 0 then Nud(k,(aux (j - k - 1) q g),d)
else Nud(k,g,(aux (j - k - 1) q d))
else if j < k then
if c = 0 then Nud(j,Feuille s,Nud(k-j-1,g,d))
else Nud(j,Nud(k-j-1,g,d),Feuille s)
else (* j = k *)
failwith "Erreur irrécupérable"
in
aux i l a ;;
(*******************************************
ce type est défini dans le fichier .mli,
sa définition ne doit pas être répétée !
type arbre_de_recherche =
{ chercher : string -> bool ; insérer : string -> unit ; supprimer : string -> unit } ;;
*********************************************)
let nouvel_arbre () =
let a = ref (Feuille "")
in
{
chercher = (function s -> recherche !a s) ;
insérer = (function s -> a := insertion !a s) ;
supprimer = (function s -> a := suppression !a s)
} ;;
L'interface de la bibliothèque sur les séries formelles :
#open "num" ;;
type série_formelle ;;
and
zéro : num
and un : num
and deux : num
and trois : num
and quatre : num
and cinq : num
and six : num
and sept : num
and huit : num
and neuf : num
and dix : num
and un_demi : num
and
moins_un : num
and moins_deux : num
and moins_trois : num
and moins_quatre : num
and moins_cinq : num
and moins_six : num
and moins_sept : num
and moins_huit : num
and moins_neuf : num
and moins_dix : num
and moins_un_demi : num
and
print_SF : série_formelle -> int -> unit
and print_par_défaut : série_formelle -> unit
and installe_impression : unit -> unit
and
crée_SF_de : (num -> num) -> série_formelle
and crée_SF_expo_de : (num -> num) -> série_formelle
and intégration_SF : série_formelle -> num -> série_formelle
and dérivation_SF : série_formelle -> série_formelle
and
sinus : série_formelle
and cosinus : série_formelle
and sinus_h : série_formelle
and cosinus_h : série_formelle
and tangente : série_formelle
and tangente_h : série_formelle
and arctangente : série_formelle
and arctangente_h : série_formelle
and exponentielle : série_formelle
and ln_un_plus_z : série_formelle
and arcsinus : série_formelle
and arcsinus_h : série_formelle
and catalan : série_formelle ;;
L'implémentation de la bibliothèque sur les séries formelles :
#open "num" ;;
let crée_SF_de f =
let rec crée n =
{ Constante = f n ;
Reste = Gelé (function () -> crée (n +/ un))
}
in
crée zéro ;;
let SF_de_poly l =
let rec crée = function
| [] -> { Constante = zéro ; Reste = Gelé (function () -> crée []) }
| a :: q -> { Constante = a ; Reste = Gelé (function () -> crée q) }
in
crée l ;;
let crée_SF_expo_de f =
let rec crée n nn =
{ Constante = (f n) // nn ;
Reste = Gelé (function () -> crée (n +/ un) (nn */ (n +/ un)))
}
in
crée zéro un ;;
let dérivation_SF s =
let rec dérivation_aux s n =
{ Constante = s.Constante */ n ;
Reste = Gelé (function () -> dérivation_aux (reste_SF s) (n +/ un))
}
in
dérivation_aux (reste_SF s) un ;;
let multiplication_SF s t =
let produit_de_Cauchy a b =
let b' = rev b
in
it_list2 (fun t x y -> t +/ x */ y) zéro a b'
in
let rec multiplie_aux s t sl tl =
let sl' = s.Constante :: sl
and tl' = t.Constante :: tl
in
{ Constante = produit_de_Cauchy sl' tl' ;
Reste = Gelé (function () -> multiplie_aux (reste_SF s) (reste_SF t) sl' tl')
}
in
multiplie_aux s t [] [] ;;
let composition_SF s t =
let rec intervalle i j =
if i > j then []
else i :: (intervalle (i + 1) j)
in
let rec k_somme k s = (* k_somme 3 6 renvoie [[4; 1; 1]; [3; 2; 1]; [3; 1; 2]; ... *)
if s = 0 then []
else if k = 1 then [ [ s ] ]
else it_list
(fun ll i -> (map (function l -> i :: l) (k_somme (k - 1) (s - i))) @ ll)
[] (intervalle 1 s)
in
let coeff av bv =
let n = vect_length av - 1
in
let sbk l = it_list (fun x i -> x */ bv.(n - i)) un l
in
it_list
(fun s k -> s +/ av.(n-k) */ (it_list
(fun x l -> x +/ (sbk l))
zéro
(k_somme k n)))
zéro
(intervalle 1 n)
in
let rec aux al bl s t =
let al' = s.Constante :: al
and bl' = t.Constante :: bl
in
{ Constante = coeff (vect_of_list al') (vect_of_list bl') ;
Reste = Gelé(function () -> aux al' bl' (reste_SF s) (reste_SF t))
}
in
if t.Constante <>/ zéro then failwith "La composée a(b(z)) n'existe que si v(b) > 1" ;
{ Constante = s.Constante ;
Reste = Gelé(function () -> aux [ s.Constante ] [ t.Constante ]
(reste_SF s) (reste_SF t))
} ;;
let un_plus_z_puissance_a_SF a =
let rec aux coef k =
let k' = k +/ un
in
{ Constante = coef ;
Reste = Gelé (function () -> aux (coef */ (a -/ k) // k') k')
}
in
{ Constante = un ;
Reste = Gelé (function () -> aux a un)
} ;;
let un_sur_a_plus_z_SF a =
if a =/ zéro then failwith "1/z n'a pas de développement en série formelle" ;
let a' = zéro -/ a
in
let rec aux coeff =
{ Constante = coeff ;
Reste = Gelé (function () -> aux (coeff // a'))
}
in
aux (un // a) ;;
let puissance_SF_num s n =
let a = s.Constante
in
try
multiplication_SF_num
(composition_SF
(un_plus_z_puissance_a_SF n)
{
Constante = zéro ;
Reste = Gelé(function () -> reste_SF (multiplication_SF_num s (un // a)))
})
(if a =/ un then un else a **/ n)
with _ -> failwith "Exponentiation impossible" ;;
#open "format" ;;
Références
abstraction concrète
Bibliographie
Internet
Bibliographie
.Concepts et outils de la programmation .[1]
.Accart Hardin T., Donzeau-Gouge Vigié V
.Paris, InterEditions .(1993)
.ISBN 2-7296-0419-7
.Introduction à la logique contemporaine .[2]
.Blanché Robert
.Paris, Armand Colin .(1968)
.ISBN 2-200-32008-6
.The art and science of logic .[3]
.Bonevac Daniel
.Moutain View, Mayfield .(1990)
.ISBN 0-87484-805-9
.The Caml Light system release 0.5. Documentation and user's manual .[4]
.Leroy X., Mauny M
.Rocquencourt, INRIA .(1992)
.ISBN 2-7261-0748-6
.Manuel de référence du langage Caml .[5]
.Leroy Xavier, Weis Pierre
.Paris, InterEditions .(1993)
.ISBN 2-7296-0492-8
.The implementation of functionnal languages .[6]
.Peyton Jones S. L
.Englewood Ciffs, Prentice-Hall .(1987)
.ISBN 0-13-453333-9 PBK
.Functionnal programming and parallel graph rewriting .[7]
.Plasmeijer R., van Eekelen M
.Wokingham, Addison-Wesley .(1993)
.ISBN 0-201-41663-8
.Méthodes de logique .[8]
.Quine Willard V.O
.Paris, Armand Colin .(1972)
.ISBN 2-200-31081-1
.Elements of functionnal programming .[9]
.Reade Chris
.Wokingham, Addison-Wesley .(1989)
.ISBN 0-201-12915-9
.Lire Lisp .[10]
.Roy J.P., Kiremitdjian G
.(1985)
.Paris, Cedic
.ISBN 2-7124-0573-0
.Le langage Caml .[11]
.Weis Pierre, Leroy Xavier
.Paris, InterEditions .(1993)
.ISBN 2-7296-0493-6
.Approche fonctionnelle de la programmation .[12]
.Guy Cousineau, Michel Mauny
.Paris, Ediscience international .(1995)
.ISBN 2-84074-114-8
.Option informatique : cours pour la Sup MPSI .[13]
.Denis Monasse
.Paris, Librairie Vuibert .(1996)
.ISBN 2-7117-8831-8
Internet
.INRIA .[1]
http://pauillac.inria.fr/caml/index-fra.html
/ftp://ftp.inria.fr/lang/caml-light
Mémento
abstraction concrète
Syntaxe Caml
.Les définitons syntaxiques décrivent les mecanismes de construction des expressions du langage Caml
: La syntaxe des phrases du langage Caml est présentée en notation B.N.F. (Backus-Naur Form), sous la forme
identificateur_de_phrase ::= forme_syntaxique
: Dans la suite, la syntaxe d'une phrase Caml quelconque est décrite par une règle de réécriture selon le modèle
partie gauche de la règle ::= partie droite.
.Le symbole «::=» est appelé symbole de réécriture
La syntaxe de la phrase désignée par un identificateur de phrase en italique dans la partie gauche est décrite par la
.partie droite de la forme B.N.F
: La partie droite de la règle de réécriture exprime la syntaxe de la phrase par une suite de symboles qui sont
soit des identificateurs de phrase (en italique), Dans ce cas ils figurent aussi comme partie gauche•
.(d'une autre description B.N.F., et parfois de la même description (définition récursive
.(soit des symboles ou des mots-clés du langage Caml (en caractères gras non italique•
Pour éviter les confusions et les ambiguités avec les symboles utilisés dans le langage Caml, les symboles B.N.F.,
autres que le symbole de réécriture, ne sont pas employés. Par conséquent, les formes syntaxiques alternatives ou
.optionnelles, et les répétitions d'occurrences, seront définies de manière explicite, et parfois informelle
Exemple de syntaxe
expression_fonctionnelle ::= function filtrage
Dans cet exemple «expression_fonctionnelle» est l'identificateur de la forme de phrase expliquée par la
.description B.N.F., «function» est un mot-clé de Caml et «filtrage» est un identificateur de phrase
Typage Caml
.Règles de typage appliquées par le synthétiseur de types Caml
: Le typage des expressions du langage Caml est présenté en langage Caml, sous la forme
expression caml : expression de type caml
L'expression Caml «expression caml» de la partie à gauche du symbole de typage : est typée par une expression de
.type «expression de type caml» dans la partie droite
Une expression de type en Caml est formée à partir d'identificateurs de types Caml et d'expressions de types Caml
.combinés par des opérateurs sur les types
Exemples de typage
"bonjour" : string
`z` : char
function x -> x + 8 : int -> int
Dans ces exemples "bonjour", `z`, et (function x -> x+8) sont des expressions Caml, string, char et
.(int -> int), sont des expressions de type en langage Caml
Règles de typage
: Les règles de trypage sont données sous la forme
Hypothèses
----------
Conclusion
-------------------------
Evaluation Caml
.Principes d'évaluation des expressions Caml
Evaluation)a(
=> Evaluation)40(
=> 40
Evaluation)a + 5(
=> Evaluation)Evaluation)a( + Evaluation)5((
=> Evaluation)Evaluation)40( + 5(
=> Evaluation)40 + 5(
=> Evaluation)45(
=> 45
Notation et symboles
Symboles utilisés pour décrire le modèle de la machine Caml
Grammaire Caml
.Les définitions syntaxiques du langage Caml rassemblées
Syntaxe Caml
abstraction concrète
Définition simple.1
Définition multiple.2
Définition locale simple.3
(Définition locale simple (variante.4
Définitions locales emboîtées et multiples.5
(Définitions locales emboîtées et multiples (variante.6
Expression conditionnelle.7
Type construit simple.8
Type construit composé.9
Type produit.10
Type enregistrement.11
Fonctions à une variable.12
(Fonctions à n variables (1 argument.13
(Fonctions à n variables (n arguments.14
Fonction : Syntaxe 1ère forme.15
Fonction : Syntaxe 2ème forme.16
Fonction : Syntaxe 3ème forme.17
Fonction : Syntaxe 4ème forme.18
Applications.19
Définition récursive simple.20
Définition récursive multiple.21
Définition récursive locale.22
(Définition récursive locale (variante.23
Filtrage par composants.24
Filtrage par valeurs.25
Filtrage par cas.26
Gardes.27
Conditionnelle par cas.28
Fonction définie par filtrage.29
Types synonymes.30
Type somme.31
Listes.32
Définition d'une exception.33
Déclenchement d'exception.34
Gestion d'exception.35
Module de définition.36
Directive.37
Type abstrait.38
Module d'interface.39
Types polymorphes.40
Contraintes de types.41
Syntaxe de flux.42
Syntaxe du filtrage de flux.43
dernière modification : 06/12/96 .44
Commentaires
".Sans commentaire "
Bien qu’inutiles pour l’exécutant machine, et ignorés par le compilateur, les commentaires sont judicieusement
utilisés par le programmeur, pour documenter les programmes. Dans le langage Caml, ils sont encadrés par les
symboles "(*" au début et "*)" à la fin du commentaire et peuvent être placés à n'importe quelle position dans la
ligne de programme. Tous les caractères se trouvant entre "(*" et "*)" sont ignorés par le compilateur. Enfin Caml
.accepte les commentaires emboîtés
(* début de l'exemple 2
ceci est un autre commentaire en Caml
avec mise en page
et sur plusieurs lignes
(* ceci est un commentaire emboîté dans l'exemple 2 *)
(* ceci est un autre commentaire
(* emboîté à
(* plusieurs
(* niveaux d'imbrication *) *) *) *)
fin de l'exemple 2 *)
Identificateurs et expressions
Et s'il me dit un nom "
C'est celui d'un coteau
C'est celui d'une fille
Et celui d'un bateau
C'est celui d'une ville
".Et celui d'un château
.Gilles Vigneault
Identificateurs
Les identificateurs sont utilisés en Caml pour nommer des entités telles que des variables, des fonctions, des types,
des éléments de structures de ces objets comme les étiquettes (noms de champs), les constructeurs (de types ou de
valeurs). Le langage Caml distingue les majuscules des minuscules. Le premier caractère d’un identificateur est
obligatoirement une lettre. Sa longueur, le nombre des caractères qui le composent, doit être comprise dans un
intervalle de 1 à 256 caractères. Les caractères suivants peuvent être des lettres, des chiffres, des apostrophes et des
tirets, à condition que deux tirets consécutifs soient séparés par au moins un autre caractère.
Exception à la règle, deux tirets sont immédiatement consécutifs (ou adjacents) quand l’identificateur désigne le
nom d’une fonction d’un module de bibliothèque. Dans ce cas les deux tirets adjacents servent à séparer les deux
parties du nom, en premier, celui du module, et en second, celui de la fonction.
Par exemple : sort__merge désigne la fonction merge du module sort.
Les identificateurs doivent être différents des mots-clés du langage Caml tels que :
function, if, then, else, true, false, etc.
Exemples d'identificateurs valides et distincts
un, deux, A, X', X'', ALPHA, Alpha1, alpha_1, B5, autre_exemple, autre_exemple_2,
carre_d'as, FUNCTION, Then
HECTOR, Hector, hector, HecTor, heCtOr, hectoR
i_den't_if'ic_ateur12'''
Exercice 1
.Rechercher pourquoi les identificateurs suivants ne sont pas valides
.un, _deux, 'trois, 8A, carre d'as, function, then_1
Solution
Manuel : Identificateurs
Expressions
: Une expression Caml est
soit une expression atomique ou expression élémentaire non décomposable en expressions plus simples.•
Par exemple tous les identificateurs, ainsi que les constantes numériques (entières ou décimales), les
chaînes de caractères, ou encore les valeurs caractères, telles que 9, 1.047, `H`, "Jean", sont des expressions
.atomiques
soit une expression composée ou expression formée par une combinaison d'expressions plus simples•
.atomiques ou composées, et d'opérateurs
Type et valeur d'une expression
Le concept de type est à rapprocher de la notion mathématique d'ensemble. Le type d'une expression représente
.l'implémentation de l'ensemble auquel appartient la valeur obtenue par l'évaluation de cette expression
. la soustraction -,
. la multiplication *,
. la division entière /,
Le type float
Le type float implémente un sous-ensemble fini des nombres décimaux.
Les principales opérations pré-définies sur les décimaux sont :
. l'addition +.,
. la soustraction -.,
. la multiplication *.,
. la division /.
Le type bool
Le type bool implémente l'ensemble des valeurs booléennes : true et false. Les opérations
pré-définies sur les booléens sont : la négation not, la disjonction || (ou or) et la
conjonction && (ou &).
Le type char
Le type char implémente un ensemble des caractères codés par les entiers 0 à 255, les
codes 0 à 127 correspondent aux caractères ASCII. Les valeurs de ce type sont notées au
moyen du caractère qu'elles représentent, placé entre quotes, ou au moyen du numéro de
code à trois chiffres ASCII précédé du backslash \ et placé entre quotes, ou encore au
moyen d'un symbole spécial (n = nouvelle ligne, t = tabulation) précédé du backslash \ et
placé entre quotes, par exemple : `a`, `A`, `$`, `9`, `\065`, `\n`.
Le type string
Le type string implémente un sous-ensemble des chaînes de caractères de longueur [0,2
16
-1]. Les chaînes de caractères sont notées entre guillemets, par exemple : "exemple de
chaîne". L'opérateur de concaténation de chaînes de caractères est noté ^.
Par exemple : la concaténation des deux chaînes "bon" et "jour" : "bon" ^ "jour" donnera
la chaîne "bonjour".
Le type unit
Le type unit ne possède qu'une valeur, la valeur )( qui signifie «rien».
• pour les fonctions qui ne reçoivent pas d'argument (unit -> T),
Au contraire, la synthèse des types dispense de toute déclaration préalable du type de l'objet. En effet, dans ce
.second cas, le type de l'objet est déduit du contexte par l'application de règles d'inférence de types
Les expressions de type peuvent comporter des paramètres de types. Ceux-ci peuvent être remplacés par un type ou
une expression de type quelconques (opération de spécialisation). Les paramètres de types sont représentés par un
.identificateur précédé d’une apostrophe ('identificateur), par exemple 'a et 'b
Exemples d'expressions de type :
)* expressions simples de type *(
int
bool
)* expressions composées de type *(
int * int
int -> int
)char * int( -> bool
)* expressions paramétrées de type *(
'a -> 'a )* int -> int est une spécialisation de 'a -> 'a *(
'a -> int -> 'b
Constructeurs de types
.Les identificateurs qui servent à nommer les types tels que int, float, char, sont des constructeurs de types
Définitions et environnement
définitions et liaisons
Une définition construit une liaison entre un nom, la valeur à laquelle il est associé et son type. La collection des
liaisons ainsi créées est appelée environnement. Les définitions successives ont donc pour effet de modifier
.l'environnement
Dans ce qui suit, nous simplifierons en considérant la liaison comme une paire qui sera selon le contexte de l'étude :
.soit une paire (nom, valeur) dans un contexte d'évaluation, soit une paire (nom, type) dans un contexte de typage
Environnements
Dans un contexte d'évaluation, considérant un ensemble fini N d'identificateurs n et un ensemble fini V de valeurs v,
une définition mathématique de la notion d'environnement peut être donnée par : le graphe d'une bijection de N sur
.V
Ou encore, ce qui est équivalent, par : l'ensemble des paires (n, v), telles que si cet environnement contient deux
.'paires (n, v) et (n, v') alors v = v
Une autre approche représente un environnement par une liste de paires (n, v) dans laquelle la dernière liaison créée
est placée en tête de liste, et lors de la recherche d'un identificateur dans la liste, à partir de la tête, seule la première
.occurrence d'une liaison associée à cet identificateur est retenue
Le même raisonnement, dans un contexte de typage, mènera à des définitions semblables en substituant un ensemble
.fini T de types t à V
: La liste des liaisons (ni, vi) formant l'environnement Eactuel sera notée
Eactuel = (nn, vn) ... (n2, v2) (n1, v1) liaisons_Einitial
ou bien
Eactuel = (nn, vn) ... (n2, v2) (n1, v1) liaisons_Einitial
ou bien encore
Eactuel = (nn, vn) ... (n2, v2) (n1, v1) Einitial
(si j > i alors la création de la liaison (nj, vj) est plus récente que celle de (ni, vi
Définitions globales
Syntaxe : définition globale simple
définition ::=
...
définitions locales
Les définitions locales construisent des environnements temporaires durant l'évaluation de l'expression dans laquelle
elles sont incluses. Au terme de l'évaluation de l'expression contenant des définitions locales, l'environnement global
.n'est pas modifié
Syntaxe : définition locale simple
in expression_B
Exemple
#let a = -7 and b = -4 in 5*a*b + 3*)a - b( - a*a - b*b ;;
- : int = 66
Syntaxe : définition locale simple (variante)
Dans ses extensions de langage, Caml-Light procure une variante à la syntaxe précédente. Toutefois, ces extensions
.sont propres à Caml-Light, et seront éventuellement modifiées ou supprimées dans les versions futures du langage
Exemple
#5*a*b + 3*)a - b( - a*a - b*b
where a = -7 and b = -4 ;;
- : int = 66
Syntaxe : définitions locales emboîtées et multiples
définitions_emboitées_multiples ::=
définitions_emboitées_multiples ::=
expression
E':T' ,)X,T'(E:T
E1 = )a,8(E
let a = 5#
;; in 2 * a
int = 10 : -
E3_temp = )a,5(E2...............
E3 = E2
Exercice 2
Soit une session Caml dans un environnement Ei, on effectue les définitions
: suivantes
1. # let a = 30;;
2. # let b = a + 20;;
3. # let a = b + 5;;
4. # a;;
5. # b;;
6. # let c = 8 in c * c + a + b;;
7. # let a = 2 in a * a + a * b + b;;
Décrire l'environnement à chaque définition. Quelles sont les valeurs
? associées aux identificateurs a, b et c, après la dernière définition
Solution
Solution
Solution
L'expression conditionnelle
L’expression conditionnelle délivre un résultat dépendant d’une condition exprimée par une expression booléenne.
Le typage fort de Caml exige que la valeur de l’expression conditionnelle, quand la condition est vraie, et la valeur
.de l’expression conditionnelle, quand la condition est fausse, soient du même type
expression_conditionnelle ::=
if expression_booléenne
then expression_alors
else expression_sinon
-----------------------------------------------------------------
controle_d'évaluation ::=
failwith expression_chaine_message
controle_d'évaluation ::=
invalid_arg expression_chaine_message
Dans l'exemple suivant, le contrôle des valeurs admises est réalisé par
l'emploi de la fonction invalid_arg qui déclenche l'exception pré-définie
.Invalid_argument of string
#let feu = "VIOLET" in
if feu = "ROUGE" then "STOP"
else if feu = "ORANGE" then "RALENTIR"
else if feu = "VERT" then "PASSER"
else invalid_arg feu ;;
Uncaught exception: Invalid_argument "VIOLET"
Le type construit et le type produit
Le type construit
Définition d'un type construit simple
définition_type_construit ::=
définition_type_construit ::=
expression_de_type_produit ::=
valeur_tuple ::=
expression_1 , expression_2 , ... , expression_n
Une paire formée d'un entier et d'une expression de valeur entière : int * int
#7,)9+4( ;;
- : int * int = 7, 13
Le type enregistrement
Le type enregistrement est une structure composée de champs nommés par des étiquettes (noms de champs). Chaque
.champ peut contenir une valeur du type précisé dans la définition de la structure de l'enregistrement
Première approche du type enregistrement
enregistrement ::=
))étiquette_1, expression_1(,
)étiquette_2, expression_2(,
...
)étiquette_n, expression_n((
Dans ce cas, pour réaliser son implémentation, le type enregistrement est considéré comme un n_uplet de paires
(dans lequel chaque paire a pour expression de type (étiquette_i, expression_i
#)
)"sexe", `F`(,
)"age", 10(
( ;;
...
enregistrement ::=
)constructeur_1)expression_1_de_type_1(,
constructeur_2)expression_2_de_type_2(,
...
constructeur_n)expression_n_de_type_n(,
Dans ce cas, le type enregistrement est considéré comme un n_uplet de types construits dont le typage correspond à :
t_etiq_i ou encore constructeur_i of type_i
#)
Nom_prenom)"LESCURE MARIE"(,
Sexe")`F`(,
Age)10(
( ;;
type_enregistrement ::=
type nom_type = {
étiquette_1 : type_1;
étiquette_2 : type_2;
étiquette_n : type_n }
définition_enregistrement ::= {
étiquette_1 = expression_1;
étiquette_2 = expression_2;
...
étiquette_n = expression_n }
{C1=E1;...;Cn=En(}:{C1:T1;...;Cn:Tn}
ou bien
{C1=E1;...;Cn=En(}:T
Exemples
#type personne =
{nom_prenom:string; sexe:char; age:int};;
Type personne defined.
)* définition de 2 enregistrements x et y
du type personne
*(
#let x = {
nom_prenom = "LESCURE MARIE";
sexe = `F`;
age = 10 } ;;
x : personne = {nom_prenom="LESCURE MARIE"; sexe=`F`;
age=10}
#let y = {
age = 12; sexe = `M`;
nom_prenom = "VALLEE JEAN"};;
y : personne = {nom_prenom="VALLEE JEAN"; sexe=`M`;
age=12}
Accès à un champ d'un enregistrement déterminé
Pour retrouver la valeur associé à un champ d'un enregistrement, on le désigne par l'identificateur de
.l'enregistrement suivi d'un point et de l'étiquette du champ
accès_champ_enregistrement ::=
identificateur_d'enregistrement.étiquette_de_champ
Exemples
)* accès aux champs de 2 enregistrements
x et y du type personne
*(
#x.nom_prenom ;;
- : string = "LESCURE MARIE"
#y.nom_prenom ;;
- : string = "VALLEE JEAN"
#x.sexe ;;
- : char = `F`
#y.age ;;
- : int = 12
Exercice 5
: Typer les expressions Caml suivantes
1. )c + 4( >= )8 - x(
2. )"a" ^ "b"( = c
3. )4 > 8( = )"a" = "b"(
4. )"a" + 5( = )"a" + 5(
Solution
Solution
Définitions et environnement
Exercice 7
: Dans un environnement Eo, on effectue la définition
#let taux = 2 in
let alpha = 5 in
let coef = taux * alpha + alpha in
let a = taux * alpha + coef * alpha;;
? Décrire le nouvel environnement. Quel est le résultat affiché
Solution
Les fonctions
Fonctions à une variable et fonctions à un argument
.La variable est placée en argument de la fonction. Cet argument est du type de la variab
yntaxe des fonctions à une variable
expression_fonctionnelle ::=
V:T1 E:T2
function V->E:T1->T2
expression_fonctionnelle ::=
expression_fonctionnelle ::=
: 1ère solution
On construit une solution au problème en faisant appel à une fonction reste(a,b) qui nous retourne le reste de la
.division entière de a par b
let reste =
function )a,b( -> let q = a / b in a - b * q ;;
let est_pair =
function n -> if reste)n,2( = 0 then true else false ;;
: 2ème solution
.On utilisera de préférence l'opérateur arithmétique mod pré-défini à la place de la fonction reste
let est_pair =
function n -> if n mod 2 = 0 then true else false ;;
: 3ème solution
On remarque que si
)A = )if n mod 2 = 0 then true else false
)B = )n mod 2 = 0
alors, l'expression A et l'expression B sont équivalentes. En effet, si B vaut true, A retourne true, et si B est évaluée à
false, alors A = false
Fonctions anonymes
Une fonction anonyme est une expression fonctionnelle. Ainsi l'expression fonctionnelle : function var -> expr, de
« type fonctionnel : T1 -> T2, est une fonction anonyme. Elle a pour valeur fonctionnelle «x~>expr(x),Edéf
Evaluation de l'application d'une fonction anonyme
: E étant une expression du type T1 de valeur val, on évalue l'application de cette fonction anonyme à l'expression E
,En conséquence
Evaluation((function var -> expr) E) : T2 = r
Fonctions nommées
Une fonction nommée fait l'objet d'une définition formant une liaison (identificateur, valeur fonctionnelle). Ainsi,
dans la définition : let ident_f = function var -> expr , l'identificateur ident_f désigne une fonction
« nommée de type fonctionnel : T1 -> T2 , qui a pour valeur fonctionnelle «x~>expr(x);Edéf
Evaluation de l'application d'une fonction nommée
On évalue l'application de la fonction ident_f à l'expression E
(Evaluation(ident_f E
(Evaluation(«x~>expr(x);Edéf » val <=
(« Evaluation(«expr(val);Edéf <=
r <=
,En conséquence
Evaluation(ident_f E) : T2 = r
: Remarque
Si Evaluation((function var -> expr) E) : T2 = r
et Evaluation(ident_f E) : T2 = r
: on en déduit que
function var -> expr) = ident_f)
En conséquence, dans les expressions Caml, on peut remplacer le nom d'une fonction par une expression
.fonctionnelle équivalente et réciproquement
définition_fonctionnelle ::=
let identificateur =
définition_fonctionnelle ::=
let identificateur =
...
Fonction à un argument
définition_fonctionnelle ::=
définition_fonctionnelle ::=
Fonction à un argument
définition_fonctionnelle ::=
let identificateur)variable(=expression
définition_fonctionnelle ::=
Fonction à un argument
définition_fonctionnelle ::=
définition_fonctionnelle ::=
let identificateur =
Exemples
let cube = function x -> x * x * x
let cube x = x * x * x
let cube)x(= x * x * x
let cube = fun x -> x * x * x
Exemples (fonctions à plusieurs arguments)
let paire =
function x ->
function y -> )x,y(
let paire x y = )x,y(
let paire)x()y(=)x,y(
let paire = fun x -> fun y -> )x,y(
Evaluation d'une définition de fonction
La définition d'une fonction construit une liaison (identificateur, fermeture) dans l'environnement temporaire s'il
.s'agit d'une définition locale ou dans l'environnement global s'il s'agit d'une définition globale
Fonctions partielles
Les fonctions partielles sont de fonctions non totalement définies sur l'ensemble des valeurs du type correspondant à
.l'ensemble de définition
Cas de la fonction inverse
#let inverse x = 1.0 /. x ;;
inverse : float -> float = >fun>
#inverse 5.0 ;;
- : float = 0.2
#inverse 0.0 ;;
80387 Exception: divide by zero!
- : float = 0.9999976515814
Dans le cas traité en exemple, la fonction n'étant pas définie pour la valeur 0.0 de l'argument, l'exécution du
.programme conduit à une terminaison anormale de l'évaluation de l'application de la fonction à cette valeur
Pour éviter ce problème, le programmeur a la ressource de construire un type nouveau correspondant précisément à
l'ensemble des valeurs pour lesquelles la fonction est définie. Toutefois, il n'est pas toujours possible de définir le
type souhaité. Il faut alors intercepter (cf. filtrage) les valeurs pour lesquelles la fonction n'est pas définie et leur
appliquer un traitement particulier (cf. exceptions). Ainsi la fonction partielle peut être transformée en fonction
.totale
Remarque : Les spécifications de Caml ne définissent pas le traitement du débordement des opérations sur le type
float. Selon la machine utilisée, une division par 0.0 pourrait avoir des résultats très différents, du simple
.déclenchement d'une exception à l'arrêt de la machine
Types fonctionnels
Les types fonctionnels sont de la forme T1->T2 dans laquelle T1 et T2 peuvent être de n'importe quel type, y
.compris les types fonctionnels
Les applications
.Une application est une expression formée d'une fonction associée à un ou plusieurs de ses arguments
Syntaxe des applications
application d'une fonction à un argument
expression_applicative ::=
expression_f expression_p
expression_applicative ::=
E:T1->T2 E':T1
: Ainsi, à partir de l'application partielle d'une fonction, nous pouvons définir une série de nouvelles fonctions
;; " : let rubrique_titre = enchaine "Titre#
>rubrique_titre : string -> string = >fun
.l'identificateur rubrique_titre est lié à la valeur fonctionnelle créée par l'application partielle de la fonction
;; "rubrique_titre "Karel The Robot#
"string = "Titre : Karel The Robot : -
Exercice 8
.Au cours d'une session Caml, E est l'environnement initial
Typer, évaluer les phrases Caml suivantes et indiquer l'environnement
: résultant
1. # let a = 5 ;;
2. # let a = a + a ;;
3. # let v = )a = 10( ;;
4. # let f = function x -> x*x + a*a ;;
5. # f 2 ;;
6. # f f 2 ;;
7. # let rec h = function
0 -> 1
| 1 -> 1
| n -> )f)n-2( + 1( * f)n-1( ;;
8. # h 7 ;;
9. # let gamma =
function a -> function b -> a*b ;;
10.# let z = gamma 5 ;;
11.# gamma 8 4 ;;
12.# z )z 2( ;;
Solution
Solution
2( #let x = h 4 ;;
3( #let t = h 4 )function x -> x + 2( ;;
Solution
Solution
Définitions et environnement
Fonctions
Exercice 13
Construire, en Caml, la fonction base permettant de calculer la valeur de
base de décompte selon la règle de gestion :
Solution