gpt4 book ai didi

ocaml - 带元组的 let-in 表达式的求值顺序

转载 作者:行者123 更新时间:2023-12-02 15:43:59 27 4
gpt4 key购买 nike

我关于 ML 的旧笔记是这样说的

let (𝑣₁, … , 𝑣ₙ) = (𝑡₁, … , 𝑡ₙ) in 𝑡′

的语法糖
(λ 𝑣ₙ. … (λ 𝑣₁. 𝑡′)𝑡₁ … )𝑡ₙ

还有那个

let (𝑣₁, 𝑣₂) = 𝑡 𝑡′ in 𝑡″

相当于

let 𝑣 = 𝑡 𝑡′ in 
let 𝑣₂ = snd 𝑣 in
let 𝑣₁ = fst 𝑣 in
𝑡″

在哪里

  • 每个𝑣(带或不带下标)代表一个变量,
  • 每个 𝑡(有或没有下标或上标)代表一个术语,并且
  • fstsnd 分别传递一对中的第一个和第二个组件。

我想知道我是否得到了正确的评估顺序,因为我没有注意到原始引用。任何人都可以((确认或拒绝)和(提供引用))吗?

最佳答案

无论是:

let 𝑣 = 𝑡 𝑡′ in 
let 𝑣₂ = snd 𝑣 in
let 𝑣₁ = fst 𝑣 in
𝑡″

或者:

let 𝑣 = 𝑡 𝑡′ in  
let 𝑣₁ = fst 𝑣 in
let 𝑣₂ = snd 𝑣 in
𝑡″

因为 fstsnd 都没有任何副作用。 𝑡 𝑡′ 的评估中可能存在副作用,但这是在 let 绑定(bind)发生之前完成的。

此外,如:

let (𝑣₁, 𝑣₂) = 𝑡 𝑡′ in 𝑡″

𝑣₁𝑣₂ 都不依赖于绑定(bind)到另一个的值来确定其值,因此它们的绑定(bind)顺序似乎又是无关紧要的。

综上所述,那些对 SML 标准或 OCaml 实现的内部工作原理有更深入了解的人可能会给出权威答案。我只是不确定知道它如何提供任何实际好处。

实际测试

作为实际测试,运行一些代码,我们在其中绑定(bind)多个表达式的元组具有副作用以观察评估顺序。在 OCaml (5.0.0) 中,评估顺序被认为是从右到左。在评估列表的内容时,我们观察到同样的情况,其中这些表达式也有副作用。

# let f () = print_endline "f"; 1 in
let g () = print_endline "g"; 2 in
let h () = print_endline "h"; 3 in
let (a, b, c) = (f (), g (), h ()) in a + b + c;;
h
g
f
- : int = 6
# let f () = print_endline "f"; 1 in
let g () = print_endline "g"; 2 in
let h () = print_endline "h"; 3 in
let (c, b, a) = (h (), g(), f ()) in a + b + c;;
f
g
h
- : int = 6
# let f _ = print_endline "f"; 1 in
let g () = print_endline "g"; 2 in
let h () = print_endline "h"; 3 in
let a () = print_endline "a" in
let b () = print_endline "b" in
let (c, d, e) = (f [a (); b ()], g (), h ()) in
c + d + e;;
h
g
b
a
f
- : int = 6

在 SML (SML/NJ v110.99.3) 中,我们观察到相反的情况:表达式从左到右求值。

- let
= fun f() = (print "f\n"; 1)
= fun g() = (print "g\n"; 2)
= fun h() = (print "h\n"; 3)
= val (a, b, c) = (f(), g(), h())
= in
= a + b + c
= end;
f
g
h
val it = 6 : int
- let
= fun f() = (print "f\n"; 1)
= fun g() = (print "g\n"; 2)
= fun h() = (print "h\n"; 3)
= val (c, b, a) = (h(), g(), f())
= in
= a + b + c
= end;
h
g
f
val it = 6 : int
- let
= fun f _ = (print "f\n"; 1)
= fun g() = (print "g\n"; 2)
= fun h() = (print "h\n"; 3)
= fun a() = print "a\n"
= fun b() = print "b\n"
= val (c, d, e) = (f [a(), b()], g(), h())
= in
= c + d + e
= end;
a
b
f
g
h
val it = 6 : int

关于ocaml - 带元组的 let-in 表达式的求值顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74989112/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com