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

时间:2011-12-06 10:46:45

标签: haskell ocaml

在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 ...

g2在声明之前g1中使用的地方。 但这不是Ocaml的案例:

# let a = b in
  let b = 5 in
  a;;
Warning 26: unused variable b.
Error: Unbound value b

有没有理由说OCaml的行为不像Haskell?如果没有前瞻性声明,这个功能对我来说似乎很有用。

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

4 个答案:

答案 0 :(得分:18)

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

答案 1 :(得分:7)

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

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

答案 2 :(得分:5)

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

a = expr1
b = expr2

b = expr2
a = expr1

表示a定义为expr1b定义为expr2

我不知道任何OCaml,所以不能对此说些什么。

答案 3 :(得分:-1)

Haskell取消了古老的letlet rec之间的区别。 一个体面的编译器可以很好地看到它是一个简单的let还是一个包含相互递归定义并且可以相应地行动的。

(我想知道ML编译器如果以let rec开头然后只有非递归定义会做什么。当然,当进行一些重构时,这个let / let rec是一个令人讨厌的障碍。)