let quad x = let add x y = x + y in
let double x = add x x in
double x + double x;;
我无法理解它如何计算输入的 4 倍。我理解这样的表达
let x = 1 in let x = x+2 in let x = x+3 in x
评估为
(x -> x = x+2 in let x = x+3 in x) 1
let quad x = let add x y = x + y in
let double x = add x x in
double x + double x;;
我无法理解它如何计算输入的 4 倍。我理解这样的表达
let x = 1 in let x = x+2 in let x = x+3 in x
评估为
(x -> x = x+2 in let x = x+3 in x) 1
除了名称的可见性之外,您的版本与此版本没有区别:
let add x y = x + y;;
let double x = add x x;;
let quad x = double x + double x;;
思考它的方式是“在”创建一个新的范围。x 从外部范围遮蔽 x。每个 let 绑定的名称都是新的,并且与之前绑定的任何名称无关。让我们手动扩展它:
quad 1 = double 1 + double 1 主函数的变量进入函数体。在它们被使用之前,所有的 let .. in 东西都只是一个旁白。Double 被使用,所以现在我们用参数调用子函数。
double 1 = add 1 1 根据 let 的定义展开 Double。
add 1 1 = 1 + 1 根据 let 的定义展开 Add。
let add x y = x + y in ....
定义一个局部函数,当给定 anx
和 a时y
添加它们。它的定义仅在...中可用(在您的示例中,从 in 到;;
重要的是要看到它let add x y =
创建了一个新的x
绑定,这不是x
quad 中定义的。
这与 ocaml 完全等效,但可能更清楚:
let quad x = let add a b = a + b in
let double c = add c c in
double x + double x;;
根据add
最后一个表达式的定义可以改写为
double x + double x = add (double x) (double x)
再次定义add
:
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
编辑:天哪,我没注意到,用户消失了:/。