# [erlang-questions] To name a function

Raimo Niskanen <>
Thu Dec 16 17:50:28 CET 2010

```On Thu, Dec 16, 2010 at 09:06:46AM -0600, David Mercer wrote:
> On Thursday, December 16, 2010, Attila Rajmund Nohl wrote:
>
> > 2010/12/16, Morten Krogh <>:
> > > As soon as you have seen both an element that satisfies the condition
> > > and one that doesn't, you can return "some", making a full list
> > > traversal overkill for many inputs.
> >
> > Now that's a good idea:
> >
> > has_property(Fun, [E | Rest]) ->
> >     has_property(Fun, Fun(E), Rest).
> >
> > has_property(_Fun, Prev, []) ->
> >     case Prev of
> > 	true -> all;
> > 	false -> none
> >     end;
> >
> > has_property(Fun, Prev, [E | Rest]) ->
> >     Curr = Fun(E),
> >     case Curr of
> > 	Prev -> has_property(Fun, Prev, Rest);
> > 	_ -> some
> >     end.
>
> I was thinking a throw would be appropriate for the early-out:
>
> has_property(F, L) ->
> 	catch lists:foldl(fun(X, Stat) -> case {F(X), Stat} of
> 	                                  	{true, empty} -> all;
> 	                                  	{true, all} -> all;
> 	                                  	{true, none} -> throw(some);
> 	                                  	{false, empty} -> none;
> 	                                  	{false, all} -> throw(some);
> 	                                  	{false, none} -> none
> 	                                  end
> 	                  end,
> 	                  empty, L).

Preparing a catch and cleaning up is more expensive than just returning a
value. Here is a shorter variant (also not tested) of Pierpaolo Bernardi's
suggestion, returning true | false | ambivalent.

categorize(P, []) when is_function(P, 1) ->
ambivalent;
categorize(P, [X|Xs]) ->
case P(X) of
true ->
lists:all(P, Xs) orelse ambivalent;
false ->
lists:any(P, Xs) andalso ambivalent;
end.

With these return values Attila Rajmund Nohl's suggestion also gets shorter:

categorize(P, []) when is_function(P, 1) ->
ambivalent;
categorize(P, [X|Xs]) ->
case P(X) of
Bool when is_boolean(Bool) ->
categorize(P, Xs, P(X))
end.

categorize(P, [], Bool) ->
Bool;
categorize(P, [X|Xs], Bool) ->
case P(X) of
Bool ->
categorize(P, Xs, Bool);
Other when is_boolean(Other) ->
ambivalent
end.

Also not tested.

>
>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB
```