DISQUS

Valkertown Blog: Writting Circular Lists in Erlang

  • nonme · 9 months ago
    keep two lists {A, B} one in normal order the other reversed
    To move forward do this

    forward({[H|T],B}) -> {T, [H|B]};
    forward({[], B}) -> forward({reverse(B),[]})

    bawards is the opposite
  • deepspawn · 9 months ago
    Thanks, I'll give it a try and do a benchmark to see if It's better to
    the other solution in the above comments.
  • zaphar · 9 months ago
    The key is to process the list in one pass. So if I read your intent above correctly then the following should work:

    %% append the Push element to the beginning of the list while dropping the last element
    circular(List, Push) ->
    [Push] ++ drop_last(List).

    %% drop the last element from the list
    drop_last([_]) ->
    [];
    drop_last([H|T]) ->
    [H | drop_last(T)].
  • deepspawn · 9 months ago
    Nice, I'm just repeating what I have read so far but

    [Push] ++ drop_last(List)

    Wouldn't it be better written as:

    [ Push | drop_last(List)]

    Anyway, ++ is discouraged since it makes a copy of the left operator and with long lists it would be highly inefficient, in this case it wouldn't be much of a problem but I still like more how the second one looks.

    Thank you a lot for this idea, I'm guessing it's probably the best way to write it on erlang.
  • zaphar · 9 months ago
    yeah ++ is less efficient. [Push | drop_last(List)] would be better. That's what I get for coding when I'm tired. but the basic concept is the same.