Как выполнить конкатенацию списков «правильным» способом (с использованием хвостовой рекурсии)

Я работаю над следующим упражнением на Erlang:

Напишите функцию, которая, учитывая список списки, объединит их. Пример:

concatenate([[1,2,3], [], [4,five]]) ⇒ [1,2,3,4,five].

И я придумал это:

concatenate([]) ->
    [];
concatenate([[H]|Tail]) ->
    [H|concatenate(Tail)];
concatenate([[]|Tail]) ->
    concatenate(Tail);
concatenate([[H|T]|Tail]) ->
    [H|concatenate([T|Tail])].

Что работает, но я заметил, что делаю это [T | Tail] .

Первый вопрос

Это все еще считается прямой рекурсией?

После этого я избавился от этого [T | Tail] и использовал вместо него аккумулятор (как показано ниже).

Второй вопрос

Теперь второй код считается хвостовой рекурсией?

Книга намекает на использование вспомогательной функции (что и делает второй код), но это кажется довольно подробным. Это потому, что я чего-то упускаю?

concatenate([]) ->
    [];
concatenate([[H]|Tail]) ->
    [H|concatenate(Tail)];
concatenate([[]|Tail]) ->
    concatenate(Tail);
concatenate([[H|T]|Tail]) ->
    [H|concatenate(T,Tail)].

concatenate([],Tail) ->
    concatenate(Tail);
concatenate([H],Tail) ->
    [H|concatenate(Tail)];
concatenate([H|T],Tail) ->
    [H|concatenate(T,Tail)].

6
задан Yasir Arsanukaev 22 February 2011 в 01:19
поделиться