खोज…


वाक्य - विन्यास

  • समारोह (सूची | आइओलिस्ट | टपल) -> फ़ंक्शन (पूंछ)।

टिप्पणियों

पुनरावर्ती कार्य क्यों?

Erlang एक कार्यात्मक प्रोग्रामिंग भाषा है और किसी भी प्रकार की लूप संरचना नहीं है। कार्यात्मक प्रोग्रामिंग में सब कुछ डेटा, प्रकार और कार्यों पर आधारित है। यदि आप एक लूप चाहते हैं, तो आपको एक फ़ंक्शन बनाने की आवश्यकता है जो खुद को कॉल करता है।

पारंपरिक while या for जरूरी और वस्तु उन्मुख भाषा में पाश है कि Erlang में की तरह दर्शाया जा सकता है:

loop() ->
  % do something here
  loop().

इस अवधारणा को समझने के लिए अच्छी विधि सभी फ़ंक्शन कॉल का विस्तार करना है। हम इसे अन्य उदाहरणों पर देखेंगे।

सूची

यहाँ सूची प्रकार पर सबसे सरल पुनरावर्ती कार्य है। यह फ़ंक्शन केवल एक सूची में इसके प्रारंभ से इसके अंत तक नेविगेट करता है और अधिक कुछ नहीं करता है।

-spec loop(list()) -> ok.
loop([]) ->
  ok;
loop([H|T]) ->
  loop(T).

आप इसे इस तरह कह सकते हैं:

loop([1,2,3]). % will return ok.

यहाँ पुनरावर्ती कार्य विस्तार:

loop([1|2,3]) ->
  loop([2|3]) ->
    loop([3|]) ->
      loop([]) ->
        ok.

IO कार्यों के साथ पुनरावर्ती लूप

पिछला कोड कुछ नहीं करता है, और बहुत बेकार है। इसलिए, हम अब एक पुनरावर्ती फ़ंक्शन बनाएंगे जो कुछ कार्यों को निष्पादित करता है। यह कोड lists:foreach/2 समान है lists:foreach/2

-spec loop(list(), fun()) -> ok.
loop([], _) ->
  ok;
loop([H|T], Fun) 
  when is_function(Fun) ->
    Fun(H),
    loop(T, Fun).

आप इसे इस तरह से कॉल कर सकते हैं:

Fun = fun(X) -> io:format("~p", [X]) end.
loop([1,2,3]).

यहाँ पुनरावर्ती कार्य विस्तार:

loop([1|2,3], Fun(1)) ->
  loop([2|3], Fun(2)) ->
    loop([3|], Fun(3)) ->
      loop([], _) ->
        ok.

आप lists:foreach/2 साथ तुलना कर सकते हैं lists:foreach/2 आउटपुट:

lists:foreach(Fun, [1,2,3]).

सूची में संशोधित लूप, संशोधित सूची लौटाता है

lists:map/2 समान एक और उपयोगी उदाहरण lists:map/2 । यह फ़ंक्शन एक सूची और एक अनाम फ़ंक्शन लेगा। हर बार सूची में एक मूल्य का मिलान किया जाता है, हम उस पर फ़ंक्शन लागू करते हैं।

-spec loop(A :: list(), fun()) -> list().
loop(List, Fun) 
  when is_list(List), is_function(Fun) ->
    loop(List, Fun, []).

-spec loop(list(), fun(), list()) -> list() | {error, list()}.
loop([], _, Buffer) 
  when is_list(Buffer) ->
    lists:reverse(Buffer);
loop([H|T], Fun, Buffer) 
  when is_function(Fun), is_list(Buffer) ->
    BufferReturn = [Fun(H)] ++ Buffer,
    loop(T, Fun, BufferReturn).

आप इसे इस तरह कह सकते हैं:

Fun(X) -> X+1 end.
loop([1,2,3], Fun).

यहाँ पुनरावर्ती कार्य विस्तार:

loop([1|2,3], Fun(1), [2]) ->
  loop([2|3], Fun(2), [3,2]) ->
    loop([3|], Fun(3), [4,3,2]) ->
      loop([], _, [4,3,2]) ->
        list:reverse([4,3,2]) ->
          [2,3,4].

इस फ़ंक्शन को "पूंछ पुनरावर्ती फ़ंक्शन" भी कहा जाता है, क्योंकि हम कई निष्पादन संदर्भ में संशोधित डेटा को पारित करने के लिए एक संचयकर्ता की तरह एक चर का उपयोग करते हैं।

Iolist और Bitstring

सूची की तरह, आयोलिस्ट और बिटस्ट्रिंग पर सबसे सरल कार्य है:

-spec loop(iolist()) -> ok | {ok, iolist} .
loop(<<>>) ->
  ok;
loop(<<Head, Tail/bitstring>>) ->
  loop(Tail);
loop(<<Rest/bitstring>>) ->
  {ok, Rest}

आप इसे इस तरह कह सकते हैं:

loop(<<"abc">>).

यहाँ पुनरावर्ती कार्य विस्तार:

loop(<<"a"/bitstring, "bc"/bitstring>>) ->
  loop(<<"b"/bitstring, "c"/bitstring>>) ->
    loop(<<"c"/bitstring>>) ->
      loop(<<>>) ->
        ok.

चर बाइनरी आकार पर पुनरावर्ती कार्य

यह कोड बिटस्ट्रिंग लेता है और गतिशील रूप से इसे द्विआधारी आकार को परिभाषित करता है। इसलिए, यदि हम 4 आकार, प्रत्येक 4 बिट्स सेट करते हैं, तो एक डेटा का मिलान किया जाएगा। यह पाश कुछ भी दिलचस्प नहीं है, यह सिर्फ हमारे स्तंभ है।

loop(Bitstring, Size) 
  when is_bitstring(Bitstring), is_integer(Size) ->
    case Bitstring of
      <<>> -> 
        ok;
      <<Head:Size/bitstring,Tail/bitstring>> ->
        loop(Tail, Size);
      <<Rest/bitstring>> ->
        {ok, Rest}
    end.

आप इसे इस तरह कह सकते हैं:

loop(<<"abc">>, 4).

यहाँ पुनरावर्ती कार्य विस्तार:

loop(<<6:4/bitstring, 22, 38, 3:4>>, 4) ->
  loop(<<1:4/bitstring, "bc">>, 4) ->
    loop(<<6:4/bitstring, 38,3:4>>, 4) ->
      loop(<<2:4/bitstring, "c">>, 4) ->
        loop(<<6:4/bitstring, 3:4>>, 4) ->
          loop(<<3:4/bitstring>>, 4) ->
            loop(<<>>, 4) ->
              ok.

हमारा बिटस्ट्रिंग 7 पैटर्न पर विभाजित है। क्यों? क्योंकि डिफ़ॉल्ट रूप से, एर्लैंग 8 बिट्स के बाइनरी आकार का उपयोग करते हैं, अगर हम इसे दो में विभाजित करते हैं, तो हमारे पास 4 बिट्स हैं। हमारी स्ट्रिंग 8*3=24 बिट्स है। 24/4=6 पैटर्न। अंतिम पैटर्न <<>>loop/2 फ़ंक्शन को 7 बार कहा जाता है।

कार्यों के साथ चर बाइनरी आकार पर पुनरावर्ती कार्य

अब, हम और अधिक दिलचस्प बात कर सकते हैं। यह फ़ंक्शन एक और तर्क लेता है, एक अनाम फ़ंक्शन। हर बार हम एक पैटर्न से मेल खाते हैं, यह एक इसे पारित किया जाएगा।

-spec loop(iolist(), integer(), function()) -> ok.
loop(Bitstring, Size, Fun) ->
  when is_bitstring(Bitstring), is_integer(Size), is_function(Fun) ->
        case Bitstring of
      <<>> -> 
        ok;
      <<Head:Size/bitstring,Tail/bitstring>> ->
        Fun(Head),
        loop(Tail, Size, Fun);
      <<Rest/bitstring>> ->
        Fun(Rest),
        {ok, Rest}
    end.

आप इसे इस तरह कह सकते हैं:

Fun = fun(X) -> io:format("~p~n", [X]) end.
loop(<<"abc">>, 4, Fun).

यहाँ पुनरावर्ती कार्य विस्तार:

loop(<<6:4/bitstring, 22, 38, 3:4>>, 4, Fun(<<6:4>>) ->
  loop(<<1:4/bitstring, "bc">>, 4, Fun(<<1:4>>)) ->
    loop(<<6:4/bitstring, 38,3:4>>, 4, Fun(<<6:4>>)) ->
      loop(<<2:4/bitstring, "c">>, 4, Fun(<<2:4>>)) ->
        loop(<<6:4/bitstring, 3:4>>, 4, Fun(<<6:4>>) ->
          loop(<<3:4/bitstring>>, 4, Fun(<<3:4>>) ->
            loop(<<>>, 4) ->
              ok.

बिटस्ट्रिंग पर पुनरावर्ती कार्य संशोधित बिटस्ट्रिंग लौट रहा है

यह एक lists:map/2 समान है lists:map/2 लेकिन बिटस्ट्रिंग और आयोलिस्ट के लिए।

% public function (interface).
-spec loop(iolist(), fun()) -> iolist() | {iolist(), iolist()}.
loop(Bitstring, Fun) ->
  loop(Bitstring, 8, Fun).

% public function (interface).
-spec loop(iolist(), integer(), fun()) -> iolist() | {iolist(), iolist()}.
loop(Bitstring, Size, Fun) ->
  loop(Bitstring, Size, Fun, <<>>)

% private function.
-spec loop(iolist(), integer(), fun(), iolist()) -> iolist() | {iolist(), iolist()}.
loop(<<>>, _, _, Buffer) ->
  Buffer;
loop(Bitstring, Size, Fun, Buffer) ->
  when is_bitstring(Bitstring), is_integer(Size), is_function(Fun) ->
    case Bitstring of
      <<>> -> 
        Buffer;
      <<Head:Size/bitstring,Tail/bitstring>> ->
        Data = Fun(Head),
        BufferReturn = <<Buffer/bitstring, Data/bitstring>>,
        loop(Tail, Size, Fun, BufferReturn);
      <<Rest/bitstring>> ->
        {Buffer, Rest}
    end.

यह कोड अधिक जटिल लगता है। दो फ़ंक्शन जोड़े गए थे: loop/2 और loop/3 । ये दो कार्य loop/4 लिए सरल इंटरफ़ेस हैं।

आप इसे इस तरह निष्पादित कर सकते हैं:

Fun = fun(<<X>>) -> << (X+1) >> end.
loop(<<"abc">>, Fun).
% will return <<"bcd">>

Fun = fun(<<X:4>>) -> << (X+1) >> end.
loop(<<"abc">>, 4, Fun).
% will return <<7,2,7,3,7,4>>

loop(<<"abc">>, 4, Fun, <<>>).
% will return <<7,2,7,3,7,4>>

नक्शा

Erlang में मानचित्र पर्ल में हैश के बराबर है या इसकी कुंजी / मूल्य की दुकान में पायथन में शब्दकोशों । में संग्रहीत प्रत्येक मूल्य को सूचीबद्ध करने के लिए, आप प्रत्येक कुंजी को सूचीबद्ध कर सकते हैं, और कुंजी / मूल्य जोड़ी को वापस कर सकते हैं। यह पहला लूप आपको एक विचार देता है:

loop(Map) when is_map(Map) -> 
  Keys = maps:keys(Map),
  loop(Map, Keys).

loop(_ , []) ->
  ok;
loop(Map, [Head|Tail]) ->
  Value = maps:get(Head, Map),
  io:format("~p: ~p~n", [Head, Value]),
  loop(Map, Tail).

आप इसे इस तरह निष्पादित कर सकते हैं:

Map = #{1 => "one", 2 => "two", 3 => "three"}.
loop(Map).
% will return:
% 1: "one"
% 2: "two"
% 3: "three"

प्रबंध राज्य

पुनरावर्ती फ़ंक्शन अपने राज्यों का उपयोग लूप में करते हैं। जब आप नई प्रक्रिया शुरू करते हैं, तो यह प्रक्रिया कुछ परिभाषित स्थिति के साथ बस एक लूप होगी।

अनाम फ़ंक्शन

यहाँ पिछले उदाहरण के आधार पर पुनरावर्ती अनाम कार्यों के 2 उदाहरण दिए गए हैं। सबसे पहले, सरल अनंत लूप:

InfiniteLoop = fun 
  R() -> 
    R() end.

दूसरी बात यह है कि सूची में अनाम कार्य कर रहा है:

LoopOverList = fun 
  R([]) -> ok;
  R([H|T]) ->
    R(T) end.

इन दो कार्यों को फिर से लिखा जा सकता है:

InfiniteLoop = fun loop/0.

इस मामले में, loop/0 टिप्पणियों से loop/0 संदर्भ है। दूसरे, थोड़ा और अधिक जटिल के साथ:

LoopOverLlist = fun loop/2.

यहाँ, loop/2 सूची उदाहरण से loop/2 संदर्भ है। ये दो संकेतन हैं श्लेष्मिक शर्करा।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow