关键字如何在OCaml中运行

obl*_*bla 0 ocaml

我知道如何in在OCaml中使用关键字.我的问题是编译器执行表达式的顺序.

例如,让我们采用以下代码:

let v = expr1 in expr2
Run Code Online (Sandbox Code Playgroud)

编译器首先查看expr2,然后当它v出现expr2时替换vexpr1?或者首先,它评估expr1然后应用expr2

你可能想知道我为什么要问这个奇怪的问题.这是因为我不明白以下代码的工作原理:

let rec some_function = function 
   | [] -> () 
   | t::q when (*here put a condition*) -> some_function q
   | t::q -> (*some operations here*); some_function q
in 
let s = (*some list*)
some_function s 
Run Code Online (Sandbox Code Playgroud)

这段代码是如何工作的?我的意思是当我们有递归调用some_function q然后程序直接进入in块并应用其他递归调用some_function s

Pas*_*uoq 6

当程序说let v = expr1 in expr2,OCaml首先评估expr1,然后开始评估expr2在一个环境中,该环境v与作为结果获得的值相关联expr1.

这种评估策略,按值调用,并不是唯一可行的,但它是OCaml使用的策略.

现在让我们考虑一下片段:

let rec some_function = function ...
in
let s = (*some list*)
some_function s 
Run Code Online (Sandbox Code Playgroud)

当程序包含上面的代码段时,会执行以下步骤:

  • function ...被评估.此步骤很短,因为评估function ...块并不意味着...评估内部代码.相反,评估的结果function ...是一个闭包(忘记在你的例子中适用但不是一般的优化).
  • 表示的代码(*some list*)在一个some_function绑定到上面讨论的闭包的环境中进行评估.
  • 表达式some_function ssome_function绑定到闭包的环境中进行求值,并s绑定到求值的结果(*some list*).在此环境中,此评估成功并应用闭包,这意味着some_function现在将执行定义的代码(在已提供其参数的环境中).

闭包由未评估的代码和部分环境组成.只需要为参数添加额外的绑定来扩充环境,以便包含评估代码所需的所有内容.另一方面,只要没有提供参数,评估就无法开始,因为函数的主体引用了参数.

some_function递归的事实不会改变一般方案.它只意味着当对闭包的主体进行评估时,环境还包含一个将闭合体与闭合相关联的绑定some_function,这样some_closure对身体内部的调用就像处理体外一样.