理解OCaml中的嵌套let定义

理解OCaml中的嵌套let定义,ocaml,Ocaml,我无法理解它如何计算4倍的输入。 我理解这样的表达 let quad x = let add x y = x + y in let double x = add x x in double x + double x;; 评估为 let x = 1 in let x = x+2 in let x = x+3 in x 定义一个局部函数,当给定x和y时,将它们相加。其定义仅在。。。(在您的示例中,从in到;; 重要的是要看到,它是let add

我无法理解它如何计算4倍的输入。 我理解这样的表达

let quad x = let add x y = x + y in
             let double x = add x x in
             double x + double x;;
评估为

let x = 1 in let x = x+2 in let x = x+3 in x
定义一个局部函数,当给定
x
y
时,将它们相加。其定义仅在。。。(在您的示例中,从in到
;;

重要的是要看到,它是
let add x y=
创建一个新的
x
绑定,这不是quad中定义的
x

这完全等同于ocaml,但可能更清楚:

let add x y = x + y in ....

除了名称的可见性之外,您的版本和以下版本之间没有区别:

let quad x = let add a b = a + b in
             let double c = add c c in
             double x + double x;;
认为它是“in”的方式创建了一个新的作用域。x从外部作用域阴影x。每个let绑定名称都是新的,并且与以前绑定的任何名称无关。让我们手动展开它:

quad 1=double 1+double 1主函数的变量进入函数体。所有let..in的内容在使用之前只是一个旁白。double被使用,所以现在我们使用参数调用子函数

double 1=添加1 1根据let中的定义展开double


add 1 1=1+1根据let中的定义展开add。

根据
add
的定义,最后一个表达式可以重写为

         let add x y = x + y;; 
         let double x = add x x;; 
         let quad x = double x + double x;;
同样根据
添加的定义:

double x + double x = add (double x) (double x)
现在是扩展的时候了:

add (double x) (double x) = add (add x x) (add x x)

编辑:天哪,我没有注意到,用户已经消失了:/。

我擅自将
Let Quad
更改为
Let Quad
。OCaml(像大多数编程语言一样)区分大小写!
add (double x) (double x) = add (add x x) (add x x)
add (add x x) (add x x) = (add x x) + (add x x)
                        = (x + x) + (x + x)
                        = x + x + x + x