[英]OCaml - Why doesn't the the function change its output?
My professor showed us this code today but I can't seem to understand the result of it: 我的教授今天向我们展示了这段代码,但我似乎无法理解它的结果:
# 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
??? ??? So basically, I expect to see this result:
因此,基本上,我希望看到以下结果:
- : int = 20
Why isn't this the output? 为什么这不是输出?
It is because let a
did introduce a new variable with the same name, but the function still refers to the one in its scope - it's a closure , and the variable it closed over is a constant. 这是因为
let a
引入了一个具有相同名称的新变量,但是该函数在其作用域内仍引用该变量-这是一个闭包 ,而其关闭的变量是一个常量。 It does not look up the variable name dynamically in the scope from where it is called. 它不会在调用它的范围内动态查找变量名。
You can achieve the behaviour you expected by storing a mutable reference in the variable that you can assign to: 通过将可变引用存储在可以分配给的变量中,可以实现预期的行为:
# 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
However, notice that this is generally not desired. 但是,请注意,这通常是不希望的。 Variables should be constant, so that we can argue about the function
f
always returning either 4
or 8
when it is called, instead of having the result depend on where and when which value was assigned to the reference cell. 变量应该是常量,以便我们可以争论函数
f
在被调用时总是返回4
或8
,而不是让结果取决于在何处以及何时将值分配给参考单元。 Avoid them where you can. 尽可能避免它们。 In this particular example, one could do it like this:
在此特定示例中,可以这样执行:
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));;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.