是否可以在Erlang中创建一个未绑定的变量?

时间:2013-09-16 15:54:34

标签: erlang tail-recursion

我是二郎的全新人物。作为学习语言的练习,我尝试使用尾递归并且不使用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]).

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

在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似乎不支持未绑定的变量。似乎所有变量都需要分配给值。

2 个答案:

答案 0 :(得分: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的使用在函数式语言中的玩具问题中很常见,其中列表是一种重要的数据类型。

我不确定你试图用你的获得的Oz代码有多接近“是否可以在Erlang中创建类似的代码?如果没有,为什么?”他们是两个不同的语言,并做了许多不同的语法选择。

答案 1 :(得分:1)

短版

,您在Erlang中没有类似的代码。原因是因为在Erlang中变量是Single assignment variables。 在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)].

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