Elixir 这是一个尾部递归吗
我有以下代码片段:Elixir 这是一个尾部递归吗,elixir,Elixir,我有以下代码片段: def flatten([h|t]), do: [h] ++ flatten(t) 我是fp领域的新手,想知道这是否是尾部递归 这不是尾部递归。为了运行最后一个表达式(++,列表串联),必须保留[h],对flatten(t)的新调用将产生一个新的堆栈帧,并且由于引用了[h],因此不能仅仅替换上一个堆栈帧 换句话说,通过尾部调用优化,顶层的函数调用将替换上一个堆栈。该函数调用中的任何表达式都会提前发生,并在调用它们时使堆栈增长 大多数尾部调用优化的枚举(包括尾部递归)都使用累
def flatten([h|t]), do: [h] ++ flatten(t)
我是fp领域的新手,想知道这是否是尾部递归 这不是尾部递归。为了运行最后一个表达式(
++
,列表串联),必须保留[h]
,对flatten(t)
的新调用将产生一个新的堆栈帧,并且由于引用了[h]
,因此不能仅仅替换上一个堆栈帧
换句话说,通过尾部调用优化,顶层的函数调用将替换上一个堆栈。该函数调用中的任何表达式都会提前发生,并在调用它们时使堆栈增长
大多数尾部调用优化的枚举(包括尾部递归)都使用累加器。为了利用@GavinBrelstaff的代码,以下是尾部递归形式:
defmodule RC do
def flatten(list, acc \\ [])
def flatten([], acc), do: Enum.reverse(acc)
def flatten([h|t], acc) when is_list(h), do: flatten(h++t, acc)
def flatten([h|t], acc), do: flatten(t, [h|acc])
end
这里的无正文函数子句只是将[]建立为默认累加器。因为我们总是在做准备,为了保持秩序,我们必须在完成后反转列表。这是非常常见的事情,并且Enum.reverse在VM中得到了高度优化。你是说“fp world”吗?