可以在Erlang中定义循环列表吗?

Gok*_*kul 2 erlang list circular-list

是否可以在erlang中定义循环列表? http://en.wikipedia.org/wiki/Linked_list

第一个问题是循环列表在erlang中的意思是什么?它有两个元素,一个元素是它自己,旁边的元素是否存放在下一个元素中,存储在一个列表中?

如果是这样我可以说有可能在erlang中定义循环列表.但我需要澄清天气是我认为循环列表是在erlang?

I G*_*ICE 8

没有内置的列表机制来做到这一点.但是,您可以使用包含您访问过的元素的元组来构建一个元组.

基本结构是一个有两个列表的元组:{Old, New}.首次使用空列表时,它看起来像{[],[]}.填写列表后,将其填入New列表中:

new() -> {[], []}.

insert(X, {Old, New}) -> {Old, [X|New]}.

peek({_Old, [H|_]}) -> X.
Run Code Online (Sandbox Code Playgroud)

要在列表中移动,您要做的是首先在New列表中搜索,并将值放在旧列表中:

next({Old, [H|New]}) -> {[H|Old], New}.
Run Code Online (Sandbox Code Playgroud)

这很好,它就像我们只是丢弃旧元素一样.当我们到达列表末尾时会发生什么?我们需要修复这个函数(以及偷看函数):

peek({Old, []}) -> hd(lists:reverse(Old));
peek({_Old, [H|_]}) -> X.

next({Old, []}) -> 
    {[], lists:reverse(Old)}}.
next({Old, [H|New]}) -> 
    {[H|Old], New}}.
Run Code Online (Sandbox Code Playgroud)

如果列表中没有任何内容,则会崩溃.你也可以通过特殊的套管返回'undefined':

next({[], []}) ->
    undefined;
next({Old, []}) -> 
    {[], lists:reverse(Old)}.
next({Old, [H|New]}) -> 
    {[H|Old], New}.
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用"next","peek"和"删除"功能(见下文)来执行常规操作.我们还可以添加'prev'功能以允许向后浏览:

prev({[], []}) ->
    undefined;
prev({[], New}) -> 
    {lists:reverse(New), Old}.
prev({[H|Old], New}) -> 
    {Old, [H|New]}.

delete({Old, []}) -> {[], tl(lists:reverse(Old))};
delete({Old,[H|New]}) -> {Old, New};
Run Code Online (Sandbox Code Playgroud)

这应该涵盖大部分内容.


rvi*_*ing 5

看到erlang和erlang虚拟机,只支持不可变数据,不可能构建循环列表.如果你是以某种"非法"方式自己构建一个,那么不确定内存管理是否可以正确处理它.

  • 不变性实际上与循环列表没有任何关系.尽管Haskell使用非严格性,但Haskell具有循环列表,尽管它具有不变性,但Erlang是严格的.但是,使用lambdas可以在严格的语言中伪造非严格性. (2认同)