1

I'm doing examples from a book on Erlang. Here is the task: write the reverse function without using BIFs.

Here's what I did:

reverse([H | T]) -> [reverse(T) | [H]];
reverse([]) -> [].

Here's what this function returns:

(emacs@localhost)3> examples:reverse([1, 2, 3]).
[[[[],3],2],1]

I can't understand how can I make it return the flattened list [3, 2, 1]. Is it possible at all?

4 Answers 4

8

in the syntax [H|T], H is an element and T is a list (at least for proplist), in your code [reverse(T) | [H]] creates a list which first element is the result of reverse(T), and which tail is the single element list [H].

If you want achieve the function this way, you should use the syntax proposed by fenollp.

If you want to write an efficient code, you should avoid to make multiple intermediate copy of the partial results, and avoid non tail recursive calls (in order to limit the size of the call stack:

reverse(L) -> reverse(L,[]). % use an accumulator to create a tail recursive function

reverse([],R) -> R;
reverse([H|T],R) -> reverse(T,[H|R]). % all [H|R] can be fully evaluated before recursively calling reverse
                                      % this is what is called a tail recursive function
                                      % in addition, the construction of [H|T]
                                      % does not require to make a copy of T
Sign up to request clarification or add additional context in comments.

Comments

3

As you say you only need to flatten.

So either use lists:append/1 after your examples:reverse/1 function, or replace reverse([H | T]) -> [reverse(T) | [H]]; with reverse([H | T]) -> reverse(T) ++ [H];.

Then, the code gets algorithmically very inefficient, that's why lists:reverse/1,2 is a BIF.

Comments

1

You could use a fold:

lists:foldl(fun(X, Acc) -> [X | Acc] end, [], [1,2,3]).

Comments

0

You do not have to put the result in a list. This works fine for me:

reverse([]) -> [];
reverse([H | T]) -> reverse(T) ++ [H].

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.