OCaml中的引用透明性

3
我试图将参考透明度的定义与OCaml处理多态类型和副作用的方式协调起来。我在https://web.archive.org/web/20120729232358/http://www.csc.villanova.edu/~dmatusze/resources/ocaml/ocaml.html上阅读到,如果定义的含义不依赖于它所处的上下文,则称其为具有参考透明度。OCaml中的函数具有参考透明度,也就是说,更改上下文(其他变量和其他函数)不会更改已经定义的任何函数的含义。由于您可能经常重新定义函数,因此这一事实在调试程序时非常关键。
但是,据我所理解,这在OCaml中不可能是真的,因为在返回给定输出之前,它可能执行大量的副作用(例如写入文件和执行其他计算)。
您可能拥有一个函数f:string -> string,使得f"a"不等于f"a"。我们可以在函数体中插入一些副作用表达式,这些表达式在f的类型描述中完全看不见。
例如,f可以被定义为返回某个文件的第一行。上下文中的某个函数可能会更改影响f返回的第一行。或者更糟糕的是,上下文中的某个函数可能会删除f依赖的文件,这将使f未定义。
所以,OCaml是参考透明的吗?还是我理解有误?

你是在问关于OCaml还是这些函数?你在此描述的函数显然不具有引用透明性,因为它们并非副作用自由的。 - Jeff Mercado
1
我在询问OCaml,我认为副作用与引用透明无关。一个纯函数的记忆化版本通常会使用哈希映射来存储先前计算过的值,但即使修改哈希映射被认为是副作用,该函数本身仍将是引用透明的。 - David K.
2个回答

6

或许Matuszek想强调Ocaml的函数式方面,但我认为他在误导或直接错误。

例如,表达式(但不是语句)部分表示,OCaml是一种纯函数式语言,且OCaml声称是无状态的。而省略部分则表示:

循环也已被省略,但它们在纯函数式语言中并不是非常有用。

这很有趣,因为如果循环没有用处,它们就不会被添加到Ocaml中。


1

引用透明度意味着函数的上下文不会影响结果,而“纯”函数是仅依赖于其参数且没有副作用的函数。例如,在

# let y = 10;;
# let f x = (Printf.printf "%d+%d=%d\n" x y (x+y); x+y);;
val f : int -> int = <fun>
# f 5;;
5+10=15
- : int = 15
# let y = 3;;
val y : int = 3
# f 5;;
5+10=15
- : int = 15

我们可以看到,f是引用透明的(因为当你重新定义y时它不会改变),但是它是不纯的。


我认为f是引用不透明的,即不具备引用透明性。引用Wikipedia的说法:
这就要求表达式必须是纯的,也就是说表达式的值必须对于相同的输入是一样的,并且其评估过程不能有任何副作用。
15替换f 5将通过消除打印副作用来改变程序。
- Jess Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接