패턴 매칭

15448 단어 erlangtutorial
마지막 섹션에서 우리는 몇 가지 재귀 함수를 수행했습니다. 이제 패턴 일치를 시도하고 나중에 재귀 함수와 결합합니다.

Erlang의 경우 오류 메시지를 더 쉽게 이해할 수 있도록 오른쪽에서 왼쪽으로 실행합니다.

2> Variable = 1.
1
3> Variable = 1.
1
4> 1 = Variable.
1
5> a = Variable.
** exception error: no match of right hand side value 1


이것은 Variable을 1에 바인딩한 다음 패턴 일치를 수행하는 Erlang 쉘입니다.

3>에서 우리는 1이 되기 전에 Variable이 설정되지 않은 경우 1이 Variable에 일치하도록 패턴 일치를 시도합니다. 그러나 지금은 2>로 설정됩니다. 4>에서 Variable을 1과 일치시키려고 시도하고, 정상이면 값을 반환합니다. 5>에서 불일치가 있습니다. 여기서 오른쪽에서 왼쪽으로 일치시킵니다. 그래서 오른쪽에서 우리는 1을 일치시키려고 합니다. 일치하지 않기 때문에 실패합니다.

우리가 할 수 있는 또 다른 예는 피보나치입니다. 피보나치는 마지막 숫자와 이전 숫자에 더하기를 수행합니다. 1, 1, 2, 3, 5, 8, 13.

재귀 및 패턴 일치를 사용하여 Erlang에서 이것을 구현합니다.

-module(fibonacci).

-export([fib/1]).

fib(0) ->
    0;
fib(1) ->
    1;
fib(N) ->
    fib(N-1) + fib(N-2).


우리의 코드는 무엇을 합니까?

N이 0이고 N이 1인 경우 두 가지 기본 사례가 있습니다. 마지막 함수 절에서 N-1 및 N-2를 사용하여 fib 함수를 호출합니다.

맵, 레코드, 튜플



맵의 값에 따라 다른 작업을 수행하고 싶다고 가정해 보겠습니다.

다음과 같은 지도가 포함된 목록을 얻습니다.

[#{type => sms, text => <<"hi">>}, #{type => <<"email">>, text => <<"hi">>}]


우리는 목록에 있는 각 유형의 양을 합산하고자 합니다.

-module(pattern).

-export([sum_by_type/1,
         generate_list/0]).

sum_by_type(List) ->
    sum_by_type_aux(List, []).

sum_by_type_aux([], Acc) ->
    Acc;
sum_by_type_aux([#{type := Type} | Tail], Acc) ->
    case get_value(Acc, Type) of
        undefined ->
            sum_by_type_aux(Tail, [{Type, 1} | Acc]);
        Value ->
            NewAcc = remove_value(Acc, Type),
            sum_by_type_aux(Tail, [{Type, Value + 1} | NewAcc])
    end.

get_value([], _) ->
    undefined;
get_value([{Type, Value}|_], Type) ->
    Value;
get_value([_ | Tail], Type) ->
    get_value(Tail, Type).

remove_value(List, Type) ->
    remove_value_aux(List, Type, []).

remove_value_aux([], _, Acc) ->
    Acc;
remove_value_aux([{Type, _} | Tail], Type, Acc) ->
    remove_value_aux(Tail, Type, Acc);
remove_value_aux([Head | Tail], Type, Acc) ->
    remove_value_aux(Tail, Type, [Head | Acc]).

generate_list() ->
    [#{type => sms, text => <<"hi">>},
     #{type => email, text => <<"hi">>},
     #{type => sms, text => <<"hi">>},
     #{type => email, text => <<"hi">>},
     #{type => sms, text => <<"hi">>},
     #{type => sms, text => <<"hi">>},
     #{type => sms, text => <<"hi">>}].


다음은 합계 및 정렬을 처리하는 코드입니다. 내보낼 하나의 함수를 만들고 해당 함수는 두 개의 인수로 도우미 함수를 호출합니다. 첫 번째는 우리가 얻는 입력이고, 다른 인수는 우리가 반환할 누산기입니다.

도우미 함수는 목록의 첫 번째 요소와 일치하고 이미 합산했는지 확인합니다. 패턴 일치 및 재귀가 작동하는 방식을 더 보여주기 위해 값을 가져오고 값을 제거하기 위해 이제 고유한 함수를 만들었습니다. OTP 라이브러리에는 이를 수행하는 proplist 모듈 또는 기타 모듈이 있습니다.

4> List = pattern:generate_list().
[#{text => <<"hi">>,type => sms},
 #{text => <<"hi">>,type => email},
 #{text => <<"hi">>,type => sms},
 #{text => <<"hi">>,type => email},
 #{text => <<"hi">>,type => sms},
 #{text => <<"hi">>,type => sms},
 #{text => <<"hi">>,type => sms}]
5> pattern:sum_by_type(List).
[{sms,5},{email,2}]


목록, 튜플 및 맵을 사용하는 방법에 대한 작은 예입니다.

좋은 웹페이지 즐겨찾기