Я бы написал две функции так:
while(L) -> while(L,0).
while([], Acc) -> Acc;
while([_|T], Acc) ->
io:fwrite("~w~n",[Acc]),
while(T,Acc+1).
start() ->
X = [1,2,3,4],
while(X).
Использование пробелов для разделения определений функций дает понять, что определяются две разные функции: while / 1 и while / 2.
Я понятия не имел о [_|T]
. Это происходит после этой части в
учебник, так что это очень запутанно.
Это почти эквивалентно [H|T]
, который деконструирует список в голову и хвост, где голова - это первый элемент списка, а хвост - остальная часть списка. Имя переменной _
означает, что вас не волнует переменная, поэтому вы не будете использовать ее в теле функции. В этом случае это означает, что вам не важен заголовок списка, все, что вам нужно, - это хвост списка. Если именованная переменная используется в заголовке предложения функции, и вы не используете переменную в теле функции, то компилятор выдаст вам предупреждение.
Вот пример того, как работает деконструкция списка с сопоставлением с шаблоном:
-module(my).
-compile(export_all).
f([Head|Tail]) ->
io:format("The head of the list is: ~w~n", [Head]),
io:format("The tail of the list is: ~w~n", [Tail]).
В оболочке:
8> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
9> my:f([1, 2, 3]).
The head of the list is: 1
The tail of the list is: [2,3]
ok
10>