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取决于哪个文件f未定义的文件。

那么 OCaml 是参照透明的还是我遗漏了什么?

4

2 回答 2

6

正如您所解释的那样,Ocaml 不是引用透明的。

也许 Matuszek 想强调 Ocaml 的功能方面,但在我看来,他是误导或完全错误的。

例如,部分表达式(但不是语句)表示OCaml is a purely functional languageOCaml claims to be stateless. 部分遗漏

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

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

于 2011-05-23T00:54:18.750 回答
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 时它不会改变)但不纯。

于 2011-06-12T20:38:39.340 回答