Ocaml ML系列编译器是否对尾部调用进行过复杂的优化?
我(相信)以下函数定义是尾部递归的:Ocaml ML系列编译器是否对尾部调用进行过复杂的优化?,ocaml,sml,tail-recursion,ml,Ocaml,Sml,Tail Recursion,Ml,我(相信)以下函数定义是尾部递归的: fun is_sorted [] = true | is_sorted [x] = true | is_sorted (x::(y::xs)) = if x > y then false else is_sorted (y::xs) 简单地说,它相当于下面的声明 fun is_sorted [] = true | is_sorted [x] = true | is_sorted (x::(y::xs
fun is_sorted [] = true
| is_sorted [x] = true
| is_sorted (x::(y::xs)) =
if x > y
then false
else is_sorted (y::xs)
简单地说,它相当于下面的声明
fun is_sorted [] = true
| is_sorted [x] = true
| is_sorted (x::(y::xs)) =
(x <= y) andalso (is_sorted (y::xs))
fun已排序[]=true
|_排序为[x]=true吗
|是否已排序(x::(y::xs))=
(x如果我将您的第二个函数转换为OCaml,我会得到以下结果:
let rec is_sorted : int list -> bool = function
| [] -> true
| [_] -> true
| x :: y :: xs -> x < y && is_sorted xs
正如您所看到的,这段代码中没有递归调用,只有一个循环
(但其他人的观点是正确的,OCaml在复杂的分析方面做的并不多。这个特殊的结果似乎非常简单。)注意
A andalso B
相当于
if A then B else false
SML语言定义甚至是这样定义的。因此,B处于尾部位置。不需要进行任何花哨的优化。我可以告诉你,上次我阅读OCaml生成的程序集时,fun x->let r=g x in r
中的调用并没有被编译为尾部调用。我不这么认为。Haskell对编译器的回复相当多进行这种优化。但是OCaml的理念是将这种优化级别留给开发人员,通常它的编译器只是直接根据开发人员编写的内容进行编译。在我看来,您的函数在列表中得到了错误的答案。[3,4,2,3,4]
很好,我将修改定义,以便递归调用是正确的“is_sorted(y::xs)”编译器完全了解和的短路性质,并且可能首先将其转换为等效的条件。我希望任何半体面的编译器都能正确处理尾部调用,特别是因为它对编译器编写者来说只增加很少的工作。
if A then B else false