CAML à l'ESISAR (TP CS-110) – Anne.Benoit@imag.fr

Chapitre 1

 

1. Pour démarrer

Mise en route

  • Copier le modèle de compte-rendu

cp /home/benoit/CAML/TP/chapX.ml mon_rep_CAML/

  • Lancer l'interpréteur dans un terminal

camllight

  • Lancer xemacs avec un fond blanc

xemacs –bg white &

  • Se connecter sur le serveur isar

rlogin isar

setenv DISPLAY nom_de_terminal:0.0

Le mode Xemacs

  • C-x 2 : séparer l'écran en deux
  • C-x C-f : ouvrir le compte-rendu
  • M-x run-caml : lancer l'interpréteur Caml
  • C-c C-r : envoyer la région sélectionnée dans le compte-rendu à l'interpréteur
  • Esc ; : Créer des commentaires (* *)

 

2. Les types de base

Entiers (int)

# 1;;

- : int = 1

# 1 + 2;;

- : int = 3

Réels (float)

# 1.1;;

- : float = 1.1

# 1.1 +. 2.2;;

- : float = 3.3

Caractères (char)

# `a`;;

- : char = `a`

Textes (string)

# "bonjour";;

- : string = "bonjour"

# "bon" ^ "jour";;

- : string = "bonjour"

Booléens (bool)

# true;;

- : bool = true

# false;;

- : bool = false

N-Uplets

# 1,2,1+2;;

- : int*int*int = 1,2,3

# 2.0,true,"bon",(1,2);;

- : float * bool * string * (int*int) = 2.0,true,"bon",(1,2)

 

3. Fonctions et conditionnelles

Les fonctions

  • Définir une fonction

# let (sc: int * int->int) = function

(a,b) -> a*a + b*b ;;

sc : int*int -> int = <fun>

  • Appeler une fonction

# sc(1,2);;

- : int = 5

Remarque : bien noter la différence entre une fonction, définie par l'utilisateur ou prédéfinie, et un opérateur (+, ...) qui s'appelle en intercalant les paramètres (a + b et non pas +(a,b) )

Composition conditionnelle

if expr_booleenne then expr_de_type_t

else expr_de_type_t;;

# if true then 1 else 2;;

- : int = 1

Le type des deux expressions doit être identique.

La partie else est obligatoire.

Remarque : le type unit est le type " vide ", supprimer le else revient a avoir une partie else qui renvoie l'élement () de type unit. On peut donc le supprimer si le then renvoie du type unit.

4. Fonctions et opérateurs de base

Fonctions de conversion

t1_of_t2 : convertit un élément de type t2 en un élément de type t1

# float_of_int ;;

- : int -> float = <fun>

# float_of_int (2) ;;

- : float = 2.0

Remarque : int_of_char renvoie le code ASCII d'un caractère (et non l'entier correspondant)

Opérateurs de comparaison

= : égal

<> : différent

<, <= : inférieur, inférieur ou égal

>, >= : supérieur, supérieur ou égal

Opérateurs sur les entiers

a quo b : quotient de la division de a par b

a mod b : reste de la division de a par b

Trace d'une fonction

# trace ;;

- : string -> unit = <fun>

Rappel : unit est le type " vide "

# trace("sc");;

The function sc is now traced.

- : unit = ()

Opérateurs sur les booléens

a && b : et logique, b évalué ssi a vrai

a || b : ou logique, b évalué ssi a faux

not : non logique

Ordre du plus prioritaire au moins prioritaire :

() not && ||

5. Association nom-valeur

Définition de type

# type Intervalle == int*int;;

Type Intervalle defined

Définition de variables globales

# let x = 3;;

x : int = 3

Définition de fonction

Se reporter au paragraphe 3

Définition de variables locales

# let y = 3 in 1+y;;

- : int = 4

6. Types avec champs

Définition de types et de variables

# type T = {Nom: string; Age: int};;

Type T defined

# let x = {Nom = "toto"; Age = 18};;

x : T = {Nom = "toto"; Age = 18};;

Obtention des différents champs

# x.Nom;;

- : string = "toto"

# x.Age;;

- : int = 18

 

7. Noms formels dans une définition de fonction

N-Uplets

# let (ii: Intervalle->int)= function

(inter1) -> let (i1,s1)=inter1 in ...

équivaut à

# let (ii: Intervalle->int)= function

(i1,s1) -> ...

Types avec champs

# let (aa: T->int) = function

(id) -> id.Age;;

équivaut à

# let (aa: T->int) = function

({Nom=s; Age=a}) -> a;;

8. Généricité

# let (Premier: 'Elem * 'Elem2 -> 'Elem) = function

(a,b) -> a;;

Premier : 'a * 'b -> 'a = <fun>

ou bien on ne précise pas les types dans la déclaration de fonction :

# let Premier = function

(a,b) -> a;;

Premier : 'a * 'b -> 'a = <fun>

9. Interprétation des messages d'erreur

 

Erreurs de type

# 2 + 3.0 ;;

Toplevel input:

> 2 + 3.0 ;;

> ^^^

This expression has type float,

But is used with type int.

 

Dans le cas général, lorsqu'il y a une erreur de type, l'interpréteur Caml souligne l'expression concernée

(ici il s'agit de 3.0) et dit :

This expression has type t1,

But is used with type t2.

ce qui signifie que l'expression concernée est de type t1 alors qu'elle devrait être de type t2.

Erreurs de non-définition

# x ;;

Toplevel input:

> x ;;

> ^

The value identifier x is unbound.

 

 

La variable x n'a pas encore été définie : elle ne contient aucune valeur ou fonction. On peut la définir comme une variable globale ou comme une fonction

(paragraphe 5), on n'aura alors plus de message d'erreur.

Mauvaise utilisation des opérateurs

# 1<2<3 ;;

Toplevel input:

> 1<2<3 ;;

> ^

This expression has type int,

But is used with type bool.

 

Les opérateurs sont binaires. On peut les enchaîner lorsque les types sont compatibles (1+2+4 marche).

Dans ce cas, l'interpréteur calcule le résultat de l'opération à gauche (1+2), qui donne 3, puis calcule 3+4 qui donne 7.

Dans l'exemple à coté, 1<2 donne true, et true<3 produit une erreur de type.

Erreurs de syntaxe

# mod(1,2) ;;

Toplevel input:

> mod(1,2) ;;

> ^^^

Syntax error.

 

 

mod est un opérateur et non une fonction.

Fausses fonctions

# 1 2 ;;

Toplevel input:

> 1 2 ;;

> ^

This expression is not a function,

it cannot be applied.

 

 

Ici on utilise le modèle d'un appel de fonction : f x ou f(x) ou f(x1,x2,…), f étant une fonction.

Or dans l'exemple, f correspond à 1 qui n'est pas une fonction.

Avertissements

# let (carre: int -> int) = function

(A) -> A*A;;

Toplevel input:

> (A) -> A*A;;

> ^

Warning: the variable A starts with an upper case letter in this pattern.

carre : int -> int = <fun>

 

 

L'utilisation de noms formels commençant par des majuscules dans la définition de fonctions en Caml est à éviter. Il est préférable de garder les noms commençant par des majuscules pour les définitions de variables globales.

Ceci n'est cependant qu'un avertissement. La fonction est quand même définie et elle peut être appellée.