-1

在 Ocaml 中,我有一个用一些数字初始化的“全局”(即具有文件范围)数组,然后我对这些数字进行一些操作,然后调用一个函数将这些数字相加。现在因为这个数组是“全局的”,所以我没有费心将数组作为参数传递,最终发生的是 Ocaml 计算了初始化数字的总和(我猜是在编译时)而不是在我对数组进行操作之后已经发生过。我的问题是,为什么会发生这种情况?我花了大约 3 小时试图找出错误!这是否与 Ocaml 的无副作用部分有关?如果是这样,那么永远不会发生这样的事情的规则是什么?

谢谢

编辑:你们说得非常对,我从根本上搞砸了。这基本上是我的代码

let my_array = Array.make 10 0;;

let sum_array = ...;;

let my_fun = 
  do_stuff_with_array args;
  sum_array;;

所以当然sum_array是事先计算好的。把它改成这个,它工作,这是最好的解决方案吗?

let my_array = Array.make 10 0;;

let sum_array _ = ...;;

let my_fun = 
  do_stuff_with_array args;
  sum_array ();;
4

1 回答 1

4

OCaml 肯定不会“在编译时”计算数组元素的总和。关于 OCaml 评估顺序,您有一些不明白的地方。很难回答你的问题,因为真的没有问题,它只是告诉我们你对这个话题有点迷茫。

如果我们可以通过向您解释事情来帮助您,这很好。但是,如果您可以通过以下方式帮助我们找出您的不理解所在,这将有所帮助:

  • 给出一个不符合您预期的小源代码示例
  • 解释您期望的行为以及原因

关于 OCaml 评估顺序的一般知识是,在模块或文件中,句子是从上到下评估的,当您编写let x = a in b表达式时a,总是在 之前评估b,并且函数fun x -> a(或等价形式,例如let f x = a)评估为本身,a根本没有评估——这发生在应用程序时。

有些人喜欢有一个包含代码所有副作用的“主要”句子。经常这样写:

let () =
   (* some code that does side-effect *)

如果您在文件的其他部分编写评估并产生副作用的代码,那么它们将在这句话之前或之后被评估,具体取决于它们是在它之前还是之后。

于 2012-09-18T20:25:34.703 回答