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

bcl*_*man 5 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
Run Code Online (Sandbox Code Playgroud)

"执行这些绑定后,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
Run Code Online (Sandbox Code Playgroud)

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

我在哪里错了?

另外,为什么有val _ = t := 5必要而不是简单t := 5

谢谢,bclayman

Seb*_*olm 5

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

因此,当你这样做t := 5,你设置的两个内容t,并r于5,因为两者都包含相同的细胞.

至于你的另一个问题,t := 5是函数的函数调用:= : 'a ref * 'a -> unit.因此,t := 5是一个评估为的表达式().

val _ = t := 5简单地抛弃它()并将其变成声明而不是表达.

  • *当评估表达式"t:= 5"时,*t和r都不会改变.它们都保留对内存中特定位置的引用.评估该表达式具有改变该位置的内容的副作用.当然r现在指向这个新值 - 但不是因为r本身已被改变.一个类比:如果我指着一只狗,你指的是同一只狗,我告诉那只狗"坐"(它确实如此),你会指着一只坐着的狗 - 但不是因为我不知何故改变了你. (3认同)