[erlang-questions] To name a function
Richard O'Keefe
ok@REDACTED
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