Reference 对SML中引用的引用

Reference 对SML中引用的引用,reference,sml,Reference,Sml,我在SML学习参考资料 我编写了以下代码: let val f = (fn (s) => s := ref((!(!s)) + 2)) val x = ref (5) val y = ref x in (f y ; !x) end; 我正在尝试访问valit=7:int,尽管我的程序打印valit=5:int。我不明白为什么。我确信问题出在f函数中,但不明白为什么 我想做的是:f函数应该将参数y更新为ref(ref(7))所以x可以是ref(7)。但由于某

我在SML学习参考资料

我编写了以下代码:

let
    val f = (fn (s) => s := ref((!(!s)) + 2))
    val x = ref (5)
    val y = ref x
in
    (f y ; !x)
end;
我正在尝试访问
valit=7:int
,尽管我的程序打印
valit=5:int
。我不明白为什么。我确信问题出在
f
函数中,但不明白为什么


我想做的是:
f
函数应该将参数
y
更新为
ref(ref(7))
所以
x
可以是
ref(7)
。但由于某种原因,它不起作用。有什么问题吗?

更新y以指向新的ref不会更新x。在调用f的过程中创建了一个新的引用,我们称之为z。在电话之前,我们有:

x -> 5
y -> x
其中
->
为“指向”。通话结束后:

x -> 5
y -> z
z -> 7
编辑:实际更新x的一种可能方法是定义f,如下所示:

val f = fn r => !r := 7

当调用fy时,这将更新y指向的引用,即x。但这是否是“正确”的解决方案取决于您实际想要实现的目标。

正如Andreas Rossberg所建议的那样,
val f=fn r=>!r:=7
可能是将int ref的int更新为7的一种方法。但是你可以写任何东西,而不是
7
。相反,如果你想将间接指向的int值增加两倍,你的尝试和安德烈亚斯的建议之间的混合可能是

fun f r = !r := !(!r) + 2
这里,
!r:=…
表示“取消引用
r
以获取它指向的int ref,并更新该int ref,使其指向
”,以及
!(!r)+2
表示“两次取消引用
r
以获取它间接指向的int,并向其中添加两个”。此时,您没有更改
r
指向的内容(就像您使用
s:=ref…
),您正在使用它间接指向的值使用双取消引用
!(!r)

这方面的测试程序可以是:

val x = ref 5
val y = ref x
fun f r = !r := !(!r) + 2

fun debug str =
    print ( str ^ ": x points to " ^ Int.toString (!x) ^ " and "
          ^ "y points indirectly to " ^ Int.toString (!(!y)) ^ ".\n" )

val _ = debug "before"
val _ = f y
val _ = debug "after"
运行此测试程序将产生:

before: x points to 5 and y points indirectly to 5.
after: x points to 7 and y points indirectly to 7.

你的意思是不可能编程打印
val it=7:int
?好吧,有很多方法可以使打印结果为7,这取决于你到底想实现什么。查看我的更新。