_
désigne une variable faiblement polymorphes: il est dans une position où il ne peut pas être généralisé.
Il y a deux explications liées au polymorphisme faible dans la FAQ OCaml: voir A function obtained through partial application is not polymorphic enough et la suivante. Cela se produit généralement lorsque vous utilisez une référence non locale (dont le type ne peut être généralisé) ou lorsque vous définissez des fonctions polymorphes qui ne sont pas syntaxiquement fonctionnelles (elles ne commencent pas par fun x -> ..
mais plutôt par une application de fonction). Dans certains cas, il existe une solution facile (eta-expansion, voir la FAQ), parfois il n'y en a pas, et parfois votre programme était tout simplement défectueux.
Un exemple simple: let a = ref []
n'obtient pas le type polymorphe a list ref
. Sinon, vous pouvez utiliser à la fois int list
et bool list
, et mélanger des éléments de types différents en faisant muter la référence. Il a plutôt un type '_a list ref
. Cela signifie que le type n'est pas polymorphe, mais simplement inconnu. Une fois que vous faites quelque chose avec a
avec un type particulier, il fixe '_a
une fois pour toutes.
# let a = ref [];;
val a : '_a list ref = {contents = []}
# let sum_of_a = List.fold_left (+) 0 !a;;
val sum_of_a : int = 0
# a;;
- : int list ref = {contents = []}
Pour une explication de restriction de valeur et la restriction de la valeur « détendue » effectivement mis en œuvre dans le vérificateur de type OCaml en profondeur, voir le document Relaxing the Value Restriction par Jacques Garrigue (2004).