OCaml - 为什么函数不改变它的输出?

时间:2017-09-04 20:15:03

标签: function variables functional-programming ocaml shadowing

我的教授今天向我们展示了这段代码,但我似乎无法理解它的结果:

# let a = 2;;
val a : int = 2
# let f = fun x -> fun y -> if x = y then a + 2 else a - 10;;
val : f 'a -> 'a -> int = <fun>
# f 1 (2 - 1);;
- : int = 4
# let a = 18;;
val a : int = 18
# f 1 (2 - 1);;
- : int = 4

???所以基本上,我希望看到这个结果:

- : int = 20

为什么这不是输出?

1 个答案:

答案 0 :(得分:7)

这是因为let a确实引入了具有相同名称的 new 变量,但该函数仍然引用其范围内的变量 - 它是closure,并且它关闭的变量是一个常数。它不会在调用它的范围内动态查找变量名。

您可以通过在可以分配给的变量中存储mutable reference来实现预期的行为:

# 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

然而,请注意,这通常是不希望的。变量应该是常量,这样我们可以争论函数f在调用它时总是返回48,而不是让结果取决于哪个值和何时值是分配给参考单元格。尽可能避免使用它们。在这个特定的例子中,人们可以这样做:

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));;