All*_*ang 3 evaluation ocaml functional-programming let
我在这里遇到一些问题,我不是百分之百理解:
let x = 1 in let x = x+2 in let x = x+3 in x
我知道这个表达式的结果是6,但只是想确定计算这个表达式的顺序; 首先计算哪部分?
win*_*zki 10
您询问了表达式中评估的顺序let x=1 in let x=x+2 in ...
.订单是"从左到右"!当你有一个链时let a=b in let c=d in ...
,评估的顺序总是从左到右.
但是,在您的示例中有一个令人困惑的部分:您在每个构造中使用相同的变量名称.这很令人困惑,因为你看到了类似的东西,这看起来像是在"重新定义" 或"改变"的价值.但是在OCAML中实际上没有"改变""x"!正如上面已经指出的,这里发生的是每次引入一个新变量,所以你的例子完全等同于x
let
let x=x+1
x
x
let x = 1 in let y = x+2 in let z = y+3 in z;;
Run Code Online (Sandbox Code Playgroud)
请注意,此处评估顺序也是从左到右.(它总是由左到右的每一个链let
的构建.)在你原来的问题,你选择了把所有这些新的变量"X",而不是x
,y
和z
.这让大多数人感到困惑.最好避免这种编码风格.
但是我们如何检查我们是否正确地重命名了变量?为什么"让x = 1 in let y = x + 2"而不是"让x = 1 in let x = y + 2"?这个x=x+2
生意很混乱!那么,还有另一种理解评估的方法let x=aaa in bbb
.构造
let x=aaa in bbb
Run Code Online (Sandbox Code Playgroud)
可以始终替换为应用的以下闭包aaa
,
(fun x -> bbb) aaa
Run Code Online (Sandbox Code Playgroud)
一旦你以这种方式重写它,你可以很容易地看到两件事:首先,OCAML不会在闭包内评估"bbb",直到评估"aaa".(因此,let x=aaa in bbb
通过首先评估aaa
然后bbb
,即"从左到右"来评估收益.)其次,变量"x"被限制在闭包的主体中,因此"x"不可见在表达"aaa"中.因此,如果"aaa"包含一个名为"x"的变量,那么它之前必须已经定义了一些值,并且它与闭包内的"x"无关.为清楚起见,最好用不同的名称调用此变量.
在你的例子中:
let x=1 in let x=x+2 in let x=x+3 in x
Run Code Online (Sandbox Code Playgroud)
被重写为
(fun x -> let x=x+2 in let x=x+3 in x) 1
Run Code Online (Sandbox Code Playgroud)
然后内部let
结构也被重写:
(fun x -> (fun x -> let x=x+3 in x) x+2 ) 1
(fun x -> (fun x -> (fun x-> x) x+3) x+2 ) 1
Run Code Online (Sandbox Code Playgroud)
现在让我们重命名每个函数内部函数的参数,我们总是可以在不改变代码含义的情况下进行:
(fun x -> (fun y -> (fun z -> z) y+3) x+2 ) 1
Run Code Online (Sandbox Code Playgroud)
这是一样的
let x=1 in let y=x+2 in let z=y+3 in z
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以验证是否已正确重命名变量.
归档时间: |
|
查看次数: |
8415 次 |
最近记录: |