Reputation: 3615
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
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
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
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
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
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