[erlang-questions] To name a function

Richard O'Keefe <>
Thu Dec 16 00:34:21 CET 2010


f(Fun, List) distinguishes four cases:
  - the List is Empty
  - the List is not empty and Fun(X) is true  for all X in List
  - the List is not empty and Fun(X) is false for all X in List
  - the list is not empty and Fun(X) is sometimes true and sometimes
    false.

My first reaction is that there are two *separate* things going on
here:  counting the trues and falses, and reacting to them.

My second reaction is that I'm used to having something called "count"
that tells me how many elements have a property.

My third reaction is that empty lists are normal.

Put these together, and the first step is to write a function that
accepts a list of _any_ length and returns the counts.  This function
is more generally useful than the one originally shown.

count_true_false(Fun, List)
  when is_function(Fun, 1), is_list(List) ->
    count_true_false(Fun, List, 0, 0).

count_true_false(_, [], Y, N) ->
    {Y, N};
count_true_false(F, [X|Xs], Y, N) ->
    case F(X)
      of true  -> count_true_false(F, Xs, Y+1, N)
       ; false -> count_true_false(F, Xs, Y, N+1)
    end.


The next step is to classify a count pair.  (The count pair might
have come from something other than walking over a list.)

mixture_class(0, 0) -> empty;
mixture_class(0, _) -> none;
mixture_class(_, 0) -> all;
mixture_class(_, _) -> some.

Now we can get the original function by putting these together.

nonempty_count_class(Fun, List) ->
    case mixture_class(count_true_false(Fun, List)
      of empty -> erlang:error({badarg,List})
       ; Other -> Other
    end.

The result?  One rather peculiar function and two reusable ones.
Done in one pass with the only memory allocation being one
2-element tuple.



More information about the erlang-questions mailing list