Une fonction doit retourner une valeur dans tous les cas. Lorsqu'on utilise une structure if
pour choisir la valeur de retour, on est obligé d'expliciter le bloc du else
.
let parite n = if n mod 2 = 0 then "pair" else if n mod 2 = 1 then "impair" in print_string (parite 3);
File "test.ml", line 5, characters 11-19: This expression has type string but is here used with type unit
L'erreur est assez déroutante. Elle se situe sur le "impair"
qui est de type string
, et qui selon le compilateur devrait être de type unit
. Le type unit
est le type "action"
, comme ce sera expliqué juste après. On peut néanmoins comprendre l'erreur si on se souvient que le else
est ici implicite. Le code de la fonction est donc équivalent à :
let parite n = if n mod 2 = 0 then "pair" else if n mod 2 = 1 then "impair" else () in
Le compilateur n'a pas les moyens de voir que le bloc du else
ne sera jamais exécuté, bien qu'il soit évident pour le programmeur que le nombre est soit pair (n mod 2 = 0
) soit impair (n mod 2 = 1
). Le compilateur suppose donc que le bloc du else
puisse être exécuté. Dans ce cas, le programme fera ()
, c'est-à-dire rien du tout, d'où l'erreur. Et ne renverra pas de valeur (le type unit
correspond à ``ne rien renvoyer'', comme on va le voir juste après). Ceci est incompatible avec les valeurs de retour de type string
que sont "pair"
et "impair"
.
Le schéma général d'une fonction est le suivant :
let (...nom de la fonction...) (...noms des paramètres...) = (...actions réalisées par la fonction...) (...valeur de retour...) in
in
.