Counting in Erlang (how do I increment a variable?)

后端 未结 4 562
孤独总比滥情好
孤独总比滥情好 2021-01-05 09:46

I\'ve figured out the Erlang-style loops: tail-recursion with functions that take all the \"variables that don\'t vary\":

%% does something, 80 bytes at a ti         


        
相关标签:
4条回答
  • 2021-01-05 09:52

    Consider this implementation of a for loop in Erlang:

    for( Max, Max, F )  -> [ F(Max) ];
    for( I, Max, F )    -> [ F(I) | for( I+1, Max, F ) ].
    

    F is a function from which you can save results for values I to Max.

    0 讨论(0)
  • 2021-01-05 10:04

    Don't use the process dictionary.

    The 'normal' loop that you are expecting (ie a for loop or a do while) is usually implemented in a recursive function in Erlang so if you are incrementing a 'normal' counter do it in the function calls like you show up top.

    Don't use the process dictionary.

    In case you missed, can I just point out that you should not use the process dictionary.

    0 讨论(0)
  • 2021-01-05 10:10

    It all depends on what you are using the counter for. Anything global like the number of messages handled by q system should use ets:update_counter. If it is not global I usually just include it in the parameters like you showed.

    0 讨论(0)
  • 2021-01-05 10:11

    The standard way of incrementing a counter is as in your first example. By adding a variable to the call and incrementing it. I think that you get confused by the lack of for loops and possibility to update values.

    Note that:

    repeat(Times) when Times >= 0 -> repeat(0, Times).
    
    repeat(Times, Times) -> done;
    repeat(N, Times) ->
      do_a_side_effect,
      repeat(N + 1, Times).
    

    compiles to (more or less) the same thing as (in pseudo code):

    repeat(Times) ->
      while (N < Times) {
        do_a_side_effect
        N++
      }
      return done
    

    If you want to accumulate the result there are ways to do that as well.

    Either use the lists package or accumulate the result yourself:

    loop(File) ->
      {ok, Fd} = file:open(File),
      loop(Fd, 0, []).
    
    loop(Fd, Count, Acc) ->
      case file:read(Fd, 80) of
        {ok, Line} ->
           Result = do_something(Line, Count),
           loop(Fd, Count + 1, [Result | Acc]);
        eof ->
          file:close(File),
          {Count, lists:reverse(Acc)};
        {error, Reason} -> {error, Reason}
      end.
    

    Or something similar based on your example.

    Edit: returned Count as part of the return value as well, since it seemed to be important.

    0 讨论(0)
提交回复
热议问题