Superpolock
Superpolock

Reputation: 3615

List creation in Erlang

From "Erlang Programming" by Cesarini exercise 3-2

As I go through "Erlang Programming" I get weird list creation issues. From exercise 3-2 I wrote two similar functions.

create( 0 ) -> [];
create( N ) when N > 0 -> [ N | create( N-1 ) ].

reverse_create( 0 ) -> [];
reverse_create( N ) when N > 0 -> [ reverse_create( N-1 ) | N ].

so create(3) generates as I'd expect.

exercise3:create(3).
[3,2,1]

but reverse_create does not generate the list I expect.

exercise3:reverse_create(3).
[[[[]|1]|2]|3]

What do I need to change so that reverse_create(3) returns [1,2,3]? Thanks for explaining.

Upvotes: 6

Views: 6283

Answers (5)

ololo
ololo

Reputation: 1

This is



    reverse_create(0) -> [];
    reverse_create(N) ->
        list_create_1(1, N, []).

    list_create_1(I, N, List) when N >= I ->
        list_create_1(I + 1, N, [I | List]);
    list_create_1(_, _, List) -> List.


Upvotes: 0

Felix
Felix

Reputation: 699

I'm reading the same book, so I'm no more expert than you, but this worked for me...

create(0) -> [];
create(N) when N > 0 -> create(N-1) ++ [N].

reverse_create(0) -> [];
reverse_create(N) when N > 0 -> [N|create(N-1)].

Upvotes: 1

Chandra Patni
Chandra Patni

Reputation: 17587

reverse_create returns a list and you using that as head element to create the list which is resulting in nested lists. Try this solution:

reverse_create( 0 ) -> [];
reverse_create( N ) when N > 0 -> reverse_create( N-1 ) ++ [N].

EDIT: A much better implementation would be:

reverse_create2(N) -> reverse_create_helper(N, []).

reverse_create_helper(0, Acc) ->
    Acc;
reverse_create_helper(N, Acc) ->
    reverse_create_helper(N-1, [N|Acc]).

Upvotes: 5

YOUR ARGUMENT IS VALID
YOUR ARGUMENT IS VALID

Reputation: 2069

Normally a function such as reverse_create would be done in a tail-recursive fashion with an accumulator.

reverse_create(N) ->
    reverse_create(N, []).

reverse_create(0, Acc) ->
    Acc;
reverse_create(N, Acc) when N > 0 ->
    reverse_create(N - 1, [N | Acc]).

Upvotes: 3

OJ.
OJ.

Reputation: 29399

Of course, you could always do:

reverse_create(N) -> lists:reverse(create(N)).

This would actually run faster. But that obviously isn't the intent of the exercise. :)

Upvotes: 2

Related Questions