在let-bindings中的声明顺序,Haskell vs OCaml

use*_*265 6 ocaml haskell

在Haskell中,let/where构造中的声明顺序无关紧要,例如:

f x = let g1 x y = if x>y then show x else g2 y x
          g2 p q = g1 q p
      in ...
Run Code Online (Sandbox Code Playgroud)

在声明之前g2使用的地方g1.但这不是Ocaml的情况:

# let a = b in
  let b = 5 in
  a;;
Warning 26: unused variable b.
Error: Unbound value b
Run Code Online (Sandbox Code Playgroud)

有没有理由说OCaml不像Haskell那样?在没有前瞻性声明的情况下,此功能对我来说似乎很有用.

是因为OCaml的严格评估,还是Haskell的懒惰?

Chr*_*icz 18

OCaml使用"let rec"来指示组中的绑定何时可以相互引用.如果没有额外的"rec",绑定必须是自上而下的顺序.有关详细信息,请参阅http://caml.inria.fr/pub/docs/manual-ocaml/expr.html上的 "本地定义" .


Bau*_*ghn 7

这不是严格,但这是同一问题的症状.

Ocaml不是纯粹的功能,也就是说任意函数调用可以执行任意I/O. 这要求它们以可预测的顺序运行,这需要严格和您注意到的排序.

  • 我几乎无法想象一个更不准确,偏见和偏离主题的答案.OP在这里询问*范围规则*,这是一个自己的主题,可以独立于任何评估顺序考虑进行讨论.此外,即使在纯粹的懒惰语言中,也存在限制同时绑定范围的正当理由,例如.如果要允许隐藏先前定义的标识符. (6认同)

Pra*_*eek 5

在Haskell中,这不是因为懒惰的评估.确定哪个名称是指在编译时发生的事情,无论如何都没有执行任何操作(严格或懒惰).请记住,在Haskell中,您只是编写数学定义,而不是按顺序执行的命令.你写这些定义的顺序无关紧要.不管你说

a = expr1
b = expr2
Run Code Online (Sandbox Code Playgroud)

要么

b = expr2
a = expr1
Run Code Online (Sandbox Code Playgroud)

它意味着a定义为expr1b被定义为expr2.

我不知道任何OCaml,所以不能说什么.