Pour ce que je me souviens...
Cette écriture est comme celle qu'on utilise en maths pour des fonctions : dom -> img , le domaine de définition à gauche et l'ensemble obtenu (l'image) pour la fonction courante.
Ici, on a des types des deux cotés de la flèche.
Par exemple, « int -> int » indique une fonction qui prend un entier en paramètre et retourne un entier :
let add_2 a = a + 2;;
On peut peut mettre plus d'un paramètre dans la signature d'une fonction :
let add_a_and_b a b = a + b;;
La signature est alors : « int -> int -> int ». C'est une notation fonctionnelle qu'il faut parenthéser comme suit : (int -> int) -> int. l'évaluation de la fonction « add_a_and_b 5 4 » s'opère alors en 2 temps puisqu'il y a 2 arguments :
1/ on évalue l'appel « add_a_and_b 5 ». Cela va retourner la fonction « int -> int ». On va l'appeller f;
2/ on évalue l'appel « f 4 ». Ce coup-ci, on obtient un entier, à savoir 9.
(dans la réalité, il y a des optimisations... mais on va rester dans la théorie)
Ce type d'écriture des paramètres est la notation curryfiée et elle permet des évaluations partielles.
À la place de cette notation, on peut utiliser des n-uplets. Par exemple :
let add_a_and_b (a, b) = a + b;;
Cette fois, la signature de la fonction est « int * int -> int ». L'inconvénient de cette notation est qu'elle ne permet pas d'évaluation partielle.
Un autre exemple :
let decurr a b = (a, b);;
Sa signature : 'a -> 'b -> 'a * 'b
On prend 2 paramètres de types quelconques et on en retourne un 2-uplet.