Il est parce que let a
a fait introduire une nouvelle variable avec le même nom, mais la fonction fait toujours référence à celle de son champ d'application - c'est un closure, et la variable qu'il recouvrit est une constante. Il ne recherche pas le nom de la variable dynamiquement dans la portée à partir de laquelle il est appelé.
Vous pouvez obtenir le comportement que vous attendiez en stockant une mutable reference dans la variable que vous pouvez attribuer à:
# let a = ref 2;;
let f = fun x -> fun y -> if x = y then !a + 2 else !a - 10;;
f 1 (2 - 1);;
- : int = 4
# a := 18;;
f 1 (2 - 1);;
- : int = 20
Cependant, notez que ce qui est généralement souhaité. Les variables doivent être constantes, de sorte que nous puissions discuter de la fonction f
en renvoyant toujours 4
ou 8
lorsqu'elle est appelée, au lieu de faire dépendre le résultat de l'endroit et de la date d'attribution de la cellule de référence. Évitez-les où vous le pouvez. Dans cet exemple particulier, on pourrait le faire comme ceci:
let f a x y = 2 + if x = y then 2 else -10 in
let g = f 2 in
print_int (g 1 (2-1));
let h = f 18 in
print_int (h 1 (2-1));;
Ne pas montrer les références aux étudiants, idiot! :-p – PatJ
@PatJ Exactement ce que je pensais :-) Je vais éditer dans un avertissement approprié – Bergi
@PatJ est un imbécile impure pire qu'un imbécile pur dans ce cas? –