我正在研究SML中的参考文献。
我写了以下代码:
let
val f = (fn (s) => s := ref((!(!s)) + 2))
val x = ref (5)
val y = ref x
in
(f y ; !x)
end;
我试图访问val it = 7 : int
,但我的程序会打印val it = 5 : int
。我不明白为什么。我确信问题出在f
函数中,但无法理解原因。
我尝试做的事情:f
函数应将参数y
更新为ref(ref(7))
,以便x
可以ref(7)
。但由于某种原因,它不起作用。有什么问题?
答案 0 :(得分:1)
更新y以指向新的ref不会更新x。在调用f时创建了一个新引用,我们称之为z。在通话之前我们有:
x -> 5
y -> x
其中->
是“指向”。通话结束后:
x -> 5
y -> z
z -> 7
编辑:实际更新x的一种可能方法是按如下方式定义f:
val f = fn r => !r := 7
当调用f y时,这会更新y指向的引用,即x。但这是否是“正确”的解决方案取决于你实际想要实现的目标。
答案 1 :(得分:0)
正如Andreas Rossberg所说,val f = fn r => !r := 7
可能是将 int ref ref 的 int 更新为7的一种方法。而不是{{1}你可以写任何东西。相反,如果您希望将 int 间接指向增加2,那么您的尝试与Andreas的建议之间可能存在混合
7
此处,fun f r = !r := !(!r) + 2
表示"取消引用!r := ...
以获取它指向的 int ref ,并更新 int ref 以便相反,它指向r
",...
表示"解除引用!(!r) + 2
两次,以获得间接指向的 int ,并且添加两个。"此时,您尚未更改r
指向的内容(就像您使用r
所做的那样),并且您正在使用它指向的间接使用双重引用的值{{1} }。
这方面的测试程序可能是:
s := ref ...
运行此测试程序会产生:
!(!r)