Functional programming 以下哪些函数是尾部递归的?

Functional programming 以下哪些函数是尾部递归的?,functional-programming,ocaml,tail-recursion,Functional Programming,Ocaml,Tail Recursion,foo不是尾部递归的 let rec f1 = fun x -> if x = 0 then 1 else f1 (f1 0) in ... let rec f2 = fun x -> if x = 0 then foo x else f2 x in ... 其中foo是尾部递归的它们都是尾部递归的 let rec f1 = fun x -> if x = 0 then 1 else f1 (f1 0) in ... let rec f2 = fun x -> if

foo不是尾部递归的

let rec f1 = fun x -> if x = 0 then 1 else f1 (f1 0) in ...

let rec f2 = fun x -> if x = 0 then foo x else f2 x in ...

其中foo是尾部递归的

它们都是尾部递归的

let rec f1 = fun x -> if x = 0 then 1 else f1 (f1 0) in ...

let rec f2 = fun x -> if x = 0 then foo x else f2 x in ...
f1
但是包含两个递归调用,其中只有外部调用是尾部调用


对于
f2
/
f3
,不管
foo
是否是尾部递归的,因为它根本不是
f2
/
f3
递归的一部分。

您不应该询问函数是否是尾部递归的。您应该询问是否所有呼叫都是尾部呼叫。此外,
foo
是否是尾部递归实际上并不相关——不管它调用哪个函数,尾部调用都是尾部调用

因此,让我们一次只取一个:

let rec f3 = fun x -> if x = 0 then foo x else f3 x in ...
else
中,对
f1
的内部调用不是尾部调用。外面的是。注意,这意味着,根据定义术语的方式,您可以说此函数是尾部递归的(它有一个对自身的尾部调用),也可以说它不是(它有一个对自身的非尾部调用)

这就是为什么关注哪些调用是尾部调用而不是尾部递归非常重要!带有尾部调用消除的语言将对外部调用执行此操作,但不会对内部调用执行此操作

let rec f1 = fun x -> if x = 0 then 1 else f1 (f1 0) in ...

foo
f2
的调用在这两种情况下都是尾部调用。再说一遍,foo是什么并不重要。

那是什么语言?这些都不是递归的,因为x是按原样传递的。