Skip to main content Informatique en prépa - Lycée Malherbe 

1.2- Subtilités du OCaml

I. Tests d'égalité

En vérité, en OCaml, on a deux tests d'égalité différents : = et ==, avec l'inégalité correspondante <> et !=.

OCaml

Loading editor...

let t1 = [|1; 2; 3|];;
let t2 = [|1; 2; 3|];;
OCaml

Loading editor...

t1 = t2
OCaml

Loading editor...

t1 == t2
OCaml

Loading editor...

t1 <> t2
OCaml

Loading editor...

t1 != t2

On teste si c'est le même tableau vs un tableau avec le même contenu.

II. Polymorphisme

Le polymorphisme, c'est le fait d'avoir un type générique, qui peut se traduire par plusieurs types. En général, si vous voyez apparaitre des 'a, 'b, etc, c'est qu'on a du polymorphisme, et 'a, 'b, ... représentent des types quelconques.

Voici quelques exemples :

OCaml

Loading editor...

let first couple = 
    let (t1, _) = couple in t1;;
    
    
    
first (1, 2);;
first ("bonjour", "au revoir");;

Cette fonction à le type 'a * 'b -> 'a, c'est à dire qu'elle prend un couple, avec deux éléments de types quelconques, et qu'elle renvoie un élément du type du premier élément du couple.

OCaml

Loading editor...

let rec len (l: 'a list): int = match l with 
    |[] -> 0
    |_::q -> 1 + len q;;
    
len [1; 2; 3];;
len ['a'; 'b'];;

La fonction a pour type 'a list -> int, donc elle prend en argument une liste quelconque et renvoie un entier.

On peut également définir nos propres types polymorphes :

OCaml

Loading editor...

type 'a arbre = 
    | F of 'a
    | N of 'a * 'a arbre list;;

Ici, on a défini un arbre général qui peut stocker n'importe quel élément : l'arbre est soit

On ne peut pas créer directement un élément de type 'a arbre, il va falloir choisir un type concret.

OCaml

Loading editor...

let a = N (3, [F 2; F 1])

Ici, on a un int arbre parce que on a mis des entiers à l'intérieur.

Il existe plusieurs types polymorphes déjà définis en OCaml :

Nous n'avons pas vraiment parlé des options : il s'agit d'un type qui sert à représenter une valeur qui peut être présente, ou non.

Elle est définie ainsi :

OCaml

Loading editor...

type 'a option2 = 
    |Some2 of 'a
    |None2

Le type option existe de base en OCaml, vous n'avez pas besoin de le redéfinir. Certaines fonctions renvoient des options.

OCaml

Loading editor...

let premier l = match l with 
    |[] -> None
    |x::_ -> Some x

Plusieurs fonctions de la librairie standard OCaml sont polymorphes :

OCaml

Loading editor...

max
OCaml

Loading editor...

min
OCaml

Loading editor...

fst
OCaml

Loading editor...

snd
OCaml

Loading editor...

( @ )
OCaml

Loading editor...

List.length

III. Fonctions avancées

Fonctions mutuellement récursives

C'est très rarement utile, mais il est possible en OCaml de faire des fonctions mutuellement récursives avec le mot-clé and :

OCaml

Loading editor...

let rec est_pair n = match n with 
    | 0 -> true
    | 1 -> false 
    | _ -> est_impair (n-1)
and est_impair n = match n with 
    | 0 -> false
    | 1 -> true 
    | _ -> est_pair (n-1)
OCaml

Loading editor...

est_pair 126

Fonctions anonymes

On en a déjà un peu parlé, mais on peut écrire des fonctions anonymes avec fun arg1 arg2 ... -> ....

OCaml

Loading editor...

let plop = fun i -> i + 1;;
plop 2
OCaml

Loading editor...

(fun i -> i + 1) 2

let

OCaml

Loading editor...

let f ((x, _): 'a * 'b): 'a = x;;
OCaml

Loading editor...

let f = fun (x, y) -> x;;
let f = fun x y -> x

Curryfication

Du mathématicien Haskell Curry, qui n'a pas inventé ce concept (mais qui l'a beaucoup développé).

En OCaml, on peut appeler une fonction avec seulement une partie de ses arguments, et ça nous donne une nouvelle fonction :

OCaml

Loading editor...

max 3
OCaml

Loading editor...

let m3 = max 3;;
OCaml

Loading editor...

m3 10
OCaml

Loading editor...

m3 1

Cela fonctionne avec toutes les fonctions OCaml ! Et ça peut donner des choses étranges...

OCaml

Loading editor...

let l = [1; 2; 3; 4; 5];;

List.map ((+) 1) l

Ici, (+) est l'équivalent "fonction" de l'opérateur + : c'est une fonction qui additionne ses deux arguments.

Donc, (+) 1 est la fonction qui prend un entier et lui ajoute 1. On peut donc la donner à List.map pour l'appliquer à toute la liste.

IV. Begin ... End

Les mots-clés begin ... end en ocaml agissent exactement comme des parenthèses. On les utilise en général autour des suites d'instructions :

OCaml

Loading editor...

let print_des_trucs () = begin 
    print_int 1;
    print_newline ();
    print_endline "bonjour";
    print_char 'a'
    end
OCaml

Loading editor...

print_des_trucs ()
OCaml

Loading editor...