0

我对erlang完全陌生。作为学习语言的练习,我尝试sublist使用尾递归而不使用reverse. 这是我从该站点http://learnyousomeerlang.com/recursion获取的功能:

tail_sublist(L, N) -> reverse(tail_sublist(L, N, [])).

tail_sublist(_, 0, SubList) -> SubList;
tail_sublist([], _, SubList) -> SubList;
tail_sublist([H|T], N, SubList) when N > 0 ->
tail_sublist(T, N-1, [H|SubList]).

似乎reverse在 erlang 中的使用非常频繁。

在 Mozart/Oz 中,使用未绑定的变量很容易创建这样的函数:

proc {Sublist Xs N R}
   if N>0 then
      case Xs
      of nil then
         R = nil
      [] X|Xr then
         Unbound
      in
         R = X|Unbound
         {Sublist Xr N-1 Unbound}
      end
   else
      R=nil
   end
end

是否可以在 erlang 中创建类似的代码?如果不是,为什么?

编辑:

我想澄清一下这个问题。Oz 中的函数不使用任何辅助函数(没有附加、没有反向、没有任何外部或 BIF)。它也是使用尾递归构建的。

当我问是否可以在 erlang 中创建类似的东西时,我在问是否可以使用尾递归在 erlang 中实现一个函数或一组函数,并且只对初始列表进行一次迭代。

至此,看了你的评论和回答,我怀疑能不能做到,因为erlang好像不支持未绑定变量。似乎所有变量都需要赋值。

4

2 回答 2

1

这是一个沿途使用追加而不是在最后使用反向的版本。

subl(L, N) -> subl(L, N, []).

subl(_, 0, Accumulator) ->
    Accumulator;
subl([], _, Accumulator) ->
    Accumulator;
subl([H|T], N, Accumulator) ->
    subl(T, N-1, Accumulator ++ [H]).

我不会说“在 Erlang 中反向使用非常频繁”。我想说,reverse在列表是一种重要数据类型的函数式语言的玩具问题中,使用很常见。

我不确定您的“是否可以在 Erlang 中创建类似的代码?如果没有,为什么?”与您的 Oz 代码有多接近? 它们是两种不同的语言,并且做出了许多不同的语法选择。

于 2013-09-16T17:52:02.533 回答
1

精简版

,你不能在 Erlang 中有类似的代码。原因是因为 Erlang 中的变量是单赋值变量。在 Erlang 中根本不允许使用未绑定变量。

长版

由于您尝试比较的两种语言的范式级别存在差异,我无法想象与您上面介绍的尾递归函数相似。

但是,这也取决于您所说的类似代码的含义。所以,如果我错了,请纠正我,以下

R = X|Unbound
{Sublist Xr N-1 Unbound}

表示在递归调用返回Unbound的值之前,不会执行属性 ( R=X|Unbound ) 。在我看来,这很像以下内容:

sublist(_,0) -> [];
sublist([],_) -> [];
sublist([H|T],N) 
    when is_integer(N) ->
         NewTail = sublist(T,N-1), 
         [H|NewTail].
%% or 
%%sublist([H|T],N) 
%%    when is_integer(N) -> [H|sublist(T,N-1)].

但是这段代码不是尾递归的。

于 2013-09-17T17:53:02.420 回答