Outils pour utilisateurs

Outils du site


nsi:langages:ocaml:start

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
nsi:langages:ocaml:start [2021/10/22 23:37] – ↷ Page déplacée de nsi:tds:serveur_web20:langages:ocaml:start à nsi:langages:ocaml:start goupillwikinsi:langages:ocaml:start [2022/03/22 22:46] (Version actuelle) goupillwiki
Ligne 1: Ligne 1:
-<markdown> +====== OCaml ======
-# Présentation de OCaml+
  
-*Voir [Wikipedia](https://fr.wikipedia.org/wiki/OCaml)*+===== Présentation =====
  
-OCaml est un langage essentiellement dévellopé en France notamment par l'INRIA. C'est un langage fonctionnel. C'est un langage développé par des universitaires avec une approche très formelle. Néanmoins, c'est un langage utilisé dans l'industrie notamment quand il s'agit de prouver la validité d'un programme.+[[https://fr.wikipedia.org/wiki/OCaml|Wikipedia]] 
 + 
 +OCaml est un langage essentiellement développé en France notamment par l'INRIA. C'est un langage fonctionnel. C'est un langage développé par des universitaires avec une approche très formelle. Néanmoins, c'est un langage utilisé dans l'industrie notamment quand il s'agit de prouver la validité d'un programme.
  
 C'est un langage difficile à maîtriser, on va se limiter aux bases. C'est un langage difficile à maîtriser, on va se limiter aux bases.
  
-Pour faire des tests, vous pourrez utiliser un [environnement en ligne](https://try.ocamlpro.com/)+Pour faire des tests, vous pourrez utiliser un [[https://try.ocamlpro.com/|environnement en ligne]]
  
-## Console, programme+===== Console, programme =====
  
-Comme souvent, vous disposez à la fois d'une console dans laaquelle vous pouvez entrer des commandes qui seront exécutées immadiatement. Le prompt de la console est représenté par le caractère `#`.+Comme souvent, vous disposez à la fois d'une console dans laquelle vous pouvez entrer des commandes qui seront exécutées immédiatement. Le prompt de la console est représenté par le caractère ''#''.
  
 Vous pouvez aussi enregistrer vos commandes dans un fichier et les exécuter ensuite. Vous pouvez aussi enregistrer vos commandes dans un fichier et les exécuter ensuite.
  
-## Commentaires +===== Les éléments de programmation =====
- +
-```ocaml +
-(* ceci est un +
-commentare qui peut +
-faire plusieurs lignes *) +
-``` +
- +
-## Fin de commande +
- +
-Pour indiquer la fin d'une commande, on utilise `;;` +
- +
-## Expressions de base +
- +
-D'avord il faut disitinguer les types *int* et *float* ainsi que leurs opérateurs. `3` est un *int*. `3.` est le même nombre mais en version *float*. +
- +
-De la même façon, `+` est l'addition, mais l'addition uniquement pour les entiers. Si on veut additionner des *float*, on utilise `+.`. +
- +
-```ocaml +
-3 + 4;; (* affiche 7 en précisant le type int*) +
-3. +. 4.2;; (* affiche 7.2, type float*) +
-3 +. 4.2;; (* Erreur ! 3 n'est pas un float*) +
-``` +
- +
-## Assignation +
- +
-```ocaml +
-let x 3;; +
-``` +
- +
-Le mot clé `let` peut être compris comme le *soit* des mathématiciens : *Soit x égal à 3*. +
- +
-**Attention :** Il n'y a pas vraiment de variables en programmation fonctionnelle. `x` ne pourra pas changer ! C'est une **constante**. +
- +
-> On peut néanmoins créer des variables en OCaml, mais nous n'en parlerons pas. +
- +
-On peut aussi définir une quantité qui n'existera que le temps d'une expression : +
- +
-```ocaml +
-let a 2 in a+7;; +
-(* renvoie l'entier 9 *) +
-``` +
- +
-Dans ce qui précède, `a` n'existe que le dans le temps de l'expression qui suit. +
- +
-On peut d'ailleurs enchaîner : +
- +
-```ocaml +
-let a 3 in let b 11 in a * b;; +
-(* renvoie 33 *) +
-let r let a = 12 in a + 15;; +
-(* assigne la valeur 12 + 15 = 29 à r +
- mais a n'existe que le temps de la ligne *) +
-``` +
- +
-## Conditions +
- +
-Opérateurs classiques. On utilise `||` pour le OU, `&&` pour ET et enfin `not` pour la négation. +
- +
-```ocaml +
-let x 19;; +
-x > 3;; (* renvoie true *) +
-x < 25 && x < 0;; (* renvoie false *) +
-``` +
- +
-## Bloc de test +
- +
-```ocaml +
-if condition then instruction;; +
- +
-(* avec else *) +
-if condition then instruction else instruction;; +
-``` +
- +
-## Fonctions +
- +
-Évidemment, dans un langage fonctionnel, cette partie est très importante. +
- +
-```ocaml +
-let f fun x -> x+1;; +
-(* affiche : val f: int -> int <fun> *) +
-``` +
- +
-On a assigner à `f` une fonction en utilsant le mot-clé `fun`. Cette fonction est comme une fonction mathématique, elle consiste en l'association d'un item à un autre. +
- +
-La fonction est ici reconnue comme associant un entier à un entier. +
- +
-On pourra calculer : +
- +
-```ocaml +
-f 5;; (*affiche 6*) +
-f(5);; (*idem*) +
-``` +
- +
-Une fonction à deux variables devient un peu plus bizarre : +
- +
-```ocaml +
-let g fun x y -> x * y;; +
-(* renvoie val g: int -> int -> int <fun> *) +
-g 4 13;; (* renvoie 52 *) +
-g(4,13);; (* Erreur ! *) +
-g 4;; (* renvoie une fonction int -> int ??? *) +
-g(4);; (* idem *) +
-g(4)(13);; (* renvoie 52 *) +
-``` +
- +
-Il faut comprendre que la fonction `g` reçoit d'abord l'argument `x`, disons `x 4` pour l'exemple. `x` étant connu, on sait que le resultat sera `4 * y`. +
- +
-`g 4` produit donc une fonction `y -> 4 * y`. +
- +
-Puisque `g(4)` est une la fonction `y -> 4 * y` on peut lui appliquer un arguement : `g(4)(13)` qui fait 52. +
- +
-Remarquez que les parenthèses sont inutiles et ne servent qu'à préciser une priorité en cas de besoin. +
- +
-*Par exemple :* +
- +
-```ocaml +
-f f 5;; (* Erreur : le premier f essaie de prendre le 2e f comme argument *) +
-f (f 5);; (* C'est bon, le premier f prendra le résultat de (f 5) comme argument, c'est à dire 6*) +
-``` +
- +
-Une fonction peut avoir une une fonction comme argument. Par exemple, on pourrait définir une fonction `repete` consistant, à partir d'une fonction $x \mapsto f(x)$ d'obtenir la fonction $x \mapsto f(f(x))$. +
- +
-```ocaml +
-let repete f = fun x -> f ( f x );; +
-(* ou, c'est équivalent *) +
-let repete f x = f ( f x ) ;; +
- +
-(* Exemple d'utilisation : *) +
-let g = fun x -> 3 * x + 2;; +
-let h = repete g;; +
-(* g est la fonction x -> g(g(x)) *) +
-g(1);; (* renvoie 5 *) +
-g(5);; (* renvoie 17 *) +
-h(1);; (* renvoie 17, c'est à dire g(g(1)) *) +
-``` +
- +
-### Cas de la récurrence +
- +
-OCaml autorise les fonctions récurrentes mais il faut alors préciser le mot clé `rec`. +
- +
-Par exemple, le classique factoriel : +
- +
-```ocaml +
-let rec facto = fun n -> if n > 1 then n * (facto (n-1) ) else 1;; +
-``` +
- +
-La récurrence est le chemin privilégié. Supposez que vous souhaitiez faire la somme des `n` premiers entiers. Il serait naturel d'écrire +
- +
-```ocaml +
-(* attention code faux *) +
-let n = 10;; +
-let t = 0;; +
-for i = 1 to n do +
-  t = t + i; +
-done;; +
-print_int t;; +
-``` +
- +
-Mais cela ne fonctionne pas : La commande `t = t + i` suppose de modifier la valeur de `t` ce qui n'est en principe pas possible ! Il faut passer par une récurrence : +
- +
-```ocaml +
-let rec somme = fun n -> if n = 0 then 0 else n + somme(n-1);; +
-print_int (somme 10);; +
-``` +
- +
-La boucle est alors contenue dans l'utilisation de la récurrence. +
- +
-### Définition par cas +
- +
-La fonction `somme` précédente prévoyait deux cas : `n = 0` ou `n`quelconque. Il pourrait y avoir plus de cas et OCaml prévoit une syntaxe pour cela : +
- +
-```ocaml +
-let rec somme = function +
-  | 0 -> 0  +
-  | n -> n + somme(n-1) ;; +
-``` +
- +
-Il suffit d'énumérer les cas possibles et d'indiquer quoi faire à chaque fois. +
- +
-## Types algébriques et enregistrements +
- +
-On peut définir des types adaptés à nos besoins. +
- +
-### types produits +
- +
-Supposons que nous voulions définir un type correspondant aux coordonnées entières de points. Il nous faut un doublet d'entiers. On pourra définir : +
- +
-```ocaml +
-let coords = (2 ,3) ;; +
-(* renvoie que coords est de type int * int *) +
-``` +
- +
-On peut enregistrer un type : +
- +
-```ocaml +
-type coords = int * int;; +
-``` +
- +
-Mais ce n'est pas terrible car lors de la création +
- +
-```ocaml +
-let c = (4, 7);; +
-``` +
- +
-`c` n'est pas automatiquement reconnu comme de type `coords`. Il faudrait utiliser : +
- +
-```ocaml +
-type coords = Coords of int * int;; +
-let c = Coords(4,7);; +
-``` +
- +
-**Attention :** on ne met pas de majuscules où on veut. La commande +
- +
-```ocaml +
-type Coords = int * int (* erreur à cause de la majuscule *) +
-``` +
- +
-### types sommes +
- +
-Quand on veut qu'une variable puisse avoir plusieurs formes. Par exemple, supposons que l'on veuille faire une fonction carré acceptant des entiers ou des flottants : +
- +
-```ocaml +
-type number = Int of int | Float of float;; (* type number, entier ou flottant *) +
-let carre = function +
-  | Int i -> Int(i * i) +
-  | Float f -> Float(f *. f);; +
- +
-carre (Float 3.5) ;; (* renvoie 12.25 *) +
-carre (Int 3);; (* renvoie 9 *) +
-``` +
- +
-*Exemple :* On définit des types carré, rectangle losange, triangle et une fonction aire. +
- +
-```ocaml +
-type figure = +
-  | Carre of float +
-  | Rectangle of float * float +
-  | Triangle of float * float;; +
-let aire = function +
-  | Carre a -> a *. a +
-  | Rectangle (a, b) -> a *. b +
-  | Triangle (a, b) -> a *. b /. 2.;; +
-``` +
- +
-Ensuite on pourrait tester +
- +
-```ocaml +
-let f = (2., 5.);; +
-aire f;; (* erreur !*) +
-``` +
- +
-OCaml ne peut détecter ce qu'est `f`. Est-ce un rectangle ? un triangle ? Il faut écrire : +
- +
-```ocaml +
-let f = Rectangle(2., 5.);; +
-aire f;; (* renvoie 10. *) +
-``` +
- +
-### Utilisation des types sommes pour liste chaînées +
- +
-On veut une liste chaînée donc chaque maille est une paire avec un entier et un une flèche pointant sur le maillon suivant. Si le maillon suivant est `Nil` (*équivalent de `None`*), c'est qu'on est en fin de chaîne. +
- +
-```ocaml +
-type maillon = Nil | Maillon of int * maillon ;; +
-``` +
- +
-On peut dès lors créer la liste : +
- +
-```ocaml +
-let a = Maillon(3, Nil);; +
-let b = Maillon(5, a);; +
-let c = Maillon(9, b);; (* chaîne 9 -> 5 -> 3 *) +
-``` +
- +
-Et on peut aussi créer une fonction `longueur` : +
- +
-```ocaml +
-let rec longueur = function +
-  | Nil -> 0 +
-  | Maillon (i, m) -> 1 + (longueur m);; +
-   +
-longueur c;; (* renvoie 3*) +
-``` +
- +
-On peut remarquer que dans la défintion de `longueur` la variable `i` du cas `Maillon` n'était pas utilisée. On aurait pu dans ce cas l'indiquer clairement (*à la façon de Lua*) : +
- +
-```ocaml +
-let rec longueur = function +
-  | Nil -> 0 +
-  | Maillon (_, m) -> 1 + (longueur m);; +
-``` +
- +
-### Enregistrements +
- +
-Ils sont comme des dictionnaires. +
- +
-```ocaml +
-type point2D = { x : float ; y : float };; +
-let m = { x = 3. ; y = 4.5 };; +
-m.x (* renvoie l'attribut x de m *) +
-``` +
- +
-## Listes +
- +
-On dispose d'une structure de liste. +
- +
-```ocaml +
-let x = [4;5;17];; +
-let y = 15::x;; (* liste [15;4;5;17] *) +
-let z = 12::13;; (* erreur, pas autorisé *) +
-``` +
- +
-Avec une fonction on peut accéder au premier élément d'une liste (*head*) et à la queue (*tail*, éléments suivants). Voici un exemple donnant la somme des éléments d'uneliste.+
  
-```ocaml +  * [[.:syntaxe|Syntaxe]] 
-let rec somme = function +  [[.:fonctions|Fonctions]
-  [] -> 0                (* si la liste est vide *) +  * [[.:types_algebriques|Types algébriques et enregistrements]] 
-  | hd::tl -> hd + (somme tl);;(hd = head = 1er élément +  [[.:listes|Listes]]
-                                tl = tail = éléments suivants.*) +
-somme x;; (renvoie 26 *)                                 +
-```+
  
-</markdown> 
nsi/langages/ocaml/start.1634938671.txt.gz · Dernière modification : de goupillwiki