标准ML:关于参考细胞的困惑

时间:2015-07-19 12:32:44

标签: functional-programming sml

我正在阅读Harper的SML简介,对参考单元格有点困惑。在p。 114,他给出了以下例子:

val r = ref 0
val s = ref 0
val _ = r := 3
val x = !s + !r
val t = r
val _ = t := 5
val y = !s + !r
val z = !t  !r

“执行这些绑定后,x绑定到3,y绑定到5,z绑定到10。”

这是我对他的代码的追踪:

val r = ref 0 //allocates storage for r and sets to 0
val s = ref 0 //allocates storage for s and sets to 0
val _ = r := 3 //sets r = 3
val x = !s + !r //sets x = 0 + 3 = 3
val t = r //sets t = 3
val _ = t := 5 //sets t = 5
val y = !s + !r //sets y = 0 + 3 = 3
val z = !t  !r //sets z = 5 + 3 = 8

我的x是正确的(3),但我的y和z都是错的(我的y是3而不是5而我的z是5而不是10)。

我在哪里错了?

另外,为什么val _ = t := 5需要而不仅仅是t := 5

谢谢, bclayman

2 个答案:

答案 0 :(得分:5)

val t = r未将t设置为3.它将t设置为与r相同的参考单元格。

因此,当您执行t := 5时,您将tr的内容都设置为5,因为两者都包含相同的参考单元格。

至于您的其他问题,t := 5是函数:= : 'a ref * 'a -> unit的函数调用。因此,t := 5是一个计算结果为()的表达式。

val _ = t := 5只会丢弃()并将其转换为声明而不是表达式。

答案 1 :(得分:3)

val t = r为r创建别名。它们都指向商店中的相同位置。因此,t := 5具有改变 r 所指的存储器位置的内容的副作用(因为t和r指的是相同的位置)。因此

val y = !s + !t

设定y = 0 + 5 = 5.

你是正确的val _ = t := 5基本上与t := 5相同,尽管前者抑制了REPL中的输出(通过丢弃赋值表达式的值)。