I've been looking at some Erlang recursion examples asked earlier here on stackoverflow.
Specifically with this question Erlang basic recursion with guards
But I can't quite understand how the code works. So I have created a module to see the results it returns with a simple list with 3 elements.
-module(recursion).
-export([start/0]).
start() ->
List = [1,2,3],
Final = delete(1,List),
Final.
delete(_, []) ->
io:format("return []~n~n~n"),
[];
delete(Del, [Del|Xs]) ->
io:format("~p =:= ~p~n",[Del,Del]),
io:format("delete(~p, ~p)~n~n~n~n",[Del,Xs]),
delete(Del, Xs);
delete(Del, [X|Xs]) ->
io:format("~p =/= ~p~n",[Del,X]),
io:format(" [~p|delete(~p, ~p)]~n~n~n~n",[X,Del,Xs]),
[X|delete(Del, Xs)].
And this is the result of the log
1> recursion:start().
1 =:= 1
delete(1, [2,3])
1 =/= 2
[2|delete(1, [3])]
1 =/= 3
[3|delete(1, [])]
return [] The result of the 'Final' variable of the main function, shouldn't it be []?
bacause [3|delete(3, [])] in the last call matches with delete(_, []) -> []
or is it this way? [2,[3,[]]] -> [2,3]
[2,3]
2>
My question is: Every time the program calls delete(Del, [X|Xs]) ->, is the function returning the value to the previous call? Is it being stored somewhere? or is it just something like that? [2,[3,[]]] -> [2,3]
edit: I think I have found the solution in this link, about how the final result is built https://learnyousomeerlang.com/starting-out-for-real#lists where
13> List = [2,3,4].
[2,3,4]
14> NewList = [1|List].
[1,2,3,4]
So [2|[3|[]]] -> [2,3]
is that so?
1条答案
按热度按时间xfb7svmp1#
Yes.
This is how the function works:
1
in this case, then the head of the list isn't saved anywhere, i.e. it's skipped, and the function is called again with the tail of the list:[]
, which is very important when cons'ing elements together:if f(X) does not return a list at some point, then the list won't be a
proper
list. A proper list, such as:is equivalent to:
as you can see here:
When you write:
that's a little be tricky, and you need some experience to know how that works. You can understand things better, by writing out by hand what is happening:
Once, you've got the return value
[]
, because there are no more function calls in the result, now you can move upwards substituting:And substituting again:
which is equivalent to:
Here is a conceptually simpler version of
delete()
:However, the result is:
So, when you use an accumulator variable, you need to reverse the final result: